Come generazione casuale di punti in una circolare di distribuzione

Mi chiedo come ho potuto generare numeri casuali che appaiono in una circolare di distribuzione.

Sono in grado di generare punti casuali in una forma rettangolare e distribuzione tale che i punti sono generati all’interno del quadrato di (0 <= x < 1000, 0 <= y < 1000):

Come posso fare per generare i punti all’interno di un cerchio in modo che:

(x−500)^2 + (y−500)^2 < 250000 ?

Bisogna stare attenti a come il calcolo è fatto, tuttavia. Se l’intenzione è uniformemente distribuiti random (x,y) i valori all’interno del cerchio, quindi molti dei potenziali modi per fare il calcolo non dare quel risultato.
mathworld.wolfram.com/DiskPointPicking.html
Leggere this.

OriginaleL’autore Jack8246 | 2015-06-01

6 Replies
  1. 9
    import random
    import math
    
    # radius of the circle
    circle_r = 10
    # center of the circle (x, y)
    circle_x = 5
    circle_y = 7
    
    # random angle
    alpha = 2 * math.pi * random.random()
    # random radius
    r = circle_r * math.sqrt(random.random())
    # calculating coordinates
    x = r * math.cos(alpha) + circle_x
    y = r * math.sin(alpha) + circle_y
    
    print("Random point", (x, y))

    Nel tuo esempio circle_x 500 come circle_y è. circle_r 500.

    Un’altra versione del calcolo del raggio di ottenere distribuito uniformemente punti, basato su questa risposta

    u = random.random() + random.random()
    r = circle_r * (2 - u if u > 1 else u)
    Non so se OP ha bisogno, ma questo non essere una distribuzione uniforme.
    Questo approccio produce non uniformemente distribuito valori di (x,y) – saranno più concentrati al centro che al bordo del cerchio. Se questo è il risultato desiderato, che è bene, ma se una distribuzione uniforme è necessaria, non la prevedono.
    Questa è una perfetta opportunità per il collegamento a uno dei più grandi problemi nella teoria della probabilità: paradosso di Bertrand.
    EDIT: ho suggerito di prendere la radice quadrata di random.random() parte di r. In questo modo sarà una distribuzione uniforme.

    OriginaleL’autore f43d65

  2. 8

    PRIMA RISPOSTA:
    Una soluzione semplice potrebbe essere quella di fare un controllo per vedere se il risultato soddisfa l’equazione prima di procedere.

    Generare x, y (ci sono modi per rendere in una gamma selezionata)

    Controllare se ((x−500)^2 + (y−500)^2 < 250000) è vero
    se non, rigenerare.

    L’unico lato negativo sarebbe inefficienza.

    SECONDA RISPOSTA:

    O, si potrebbe fare qualcosa di simile a somme di riemann come per l’approssimazione di integrali. Approssimativo cerchio dividendolo in tanti rettangoli. (il più rettangoli, il più precise), e utilizzare il rettangolo algoritmo per ogni rettangolo all’interno del vostro cerchio.

    La prima risposta ha il duplice merito di essere semplice e corretto fornire una distribuzione uniforme di (x,y) i valori. L’inefficienza è relativamente piccolo, perché solo una frazione di 1(0.25*PI) delle coppie sarà respinta.
    In realtà è molto probabile che questo sarà veloce di farlo in modo “adeguato” se si utilizza un veloce generatore di numero casuale, dato che evita di trigonometria, radici, i grandi numeri e utilizza solo una chiamata a random in media.

    OriginaleL’autore Fuad

  3. 4

    Di che cosa avete bisogno è quello di campione (forma polare):

    r, theta = [math.sqrt(random.randint(0,500))*math.sqrt(500), 2*math.pi*random.random()]

    È quindi possibile trasformare r e theta torna a coordinate cartesiane x e y via

    x = 500 + r * math.cos(theta) 
    y = 500 + r * math.sin(theta)

    Correlati (anche se non in Python), ma dà l’idea.

    Come rilevato in altre risposte, questo non comporta una distribuzione uniforme dei punti.
    No, genererà distribuito uniformemente punti del disco, nota che sto generando un uniforme della radice quadrata del raggio, non il raggio (che, infatti, non comporta una distribuzione uniforme del disco).
    Ah, vero, vedo quello che stai facendo. Penso che potrebbe essere più chiara, se hai appena acquisito dal cerchio unitario, poi moltiplicati e aggiunto dopo, invece di campionamento da un r=500 cerchio.

    OriginaleL’autore vsoftco

  4. 0

    È possibile utilizzare il rifiuto di campionamento, generare un punto casuale all’interno del (2r)×(2r) quadrato che copre il cerchio, ripetere fino ad ottenere un punto all’interno del cerchio.

    OriginaleL’autore dlavila

  5. 0

    Vorrei utilizzare le coordinate polari:

    r_squared, theta = [random.randint(0,250000), 2*math.pi*random.random()]

    Allora r è sempre minore o uguale al raggio, e theta sempre tra 0 e 2*pi radianti.

    Dal momento che r non è, all’origine, è sempre convertire un vettore centrata a 500, 500, se ho capito bene

    x = 500 + math.sqrt(r_squared)*math.cos(theta)
    y = 500 + math.sqrt(r_squared)*math.sin(theta)

    Scegliere r_squared in modo casuale a causa di questo

    La distribuzione di (x,y) prodotto da questo approccio non sarà uniforme.
    x = 500 + r*math.cos(theta) y = 500 + r*math.sin(theta) Sì?
    Vedo il problema: Modificare il codice sopra: r_sqared, theta = [random.randint(0,250000), 2*math.pi*random.random()] Quindi applicare una trasformazione x = 500 + math.sqrt(r_squared)*math.cos(theta) y = 500 + math.sqrt(r_squared)*math.sin(theta)

    OriginaleL’autore fiacre

Lascia un commento