Gere um ponto random dentro de um círculo (uniformemente)

Eu preciso gerar um ponto uniformemente random dentro de um círculo de raio R.

Eu percebo que apenas escolhendo um ângulo uniformemente random no intervalo [0 … 2], e um raio uniformemente random no intervalo (0 … R ) eu terminaria com mais pontos em direção ao centro, já que para dois dados raios, os pontos no raio menor estarão mais próximos uns dos outros do que para os pontos no raio maior.

Eu encontrei uma input de blog sobre isso aqui, mas eu não entendo o raciocínio dele. Eu suponho que esteja correto, mas eu realmente gostaria de entender de onde ele obtém (2 / R 2 ) × r e como ele obtém a solução final.


Atualização: 7 anos depois de postar esta pergunta, eu ainda não tinha recebido uma resposta satisfatória sobre a questão real sobre a matemática por trás do algoritmo de raiz quadrada. Então eu passei um dia escrevendo uma resposta para mim mesmo. Link para minha resposta .

   

    Vamos nos aproximar disso como Arquimedes teria.

    Como podemos gerar um ponto uniformemente em um triângulo ABC, onde | AB | = | BC |? Vamos facilitar isso estendendo para um paralelogramo ABCD. É fácil gerar pontos uniformemente em ABCD. Nós escolhemos uniformemente um ponto random X em AB e Y no BC e escolhemos Z tal que XBYZ é um paralelogramo. Para obter um ponto uniformemente escolhido no triângulo original, dobramos todos os pontos que aparecem no ADC de volta para ABC ao longo de AC.

    Agora considere um círculo. No limite, podemos pensar nela como infinitamente muitos triângulos de isóquias ABC com B na origem e A e C na circunferência que se aproximam um do outro. Podemos escolher um desses triângulos simplesmente escolhendo um ângulo teta. Então, agora precisamos gerar uma distância do centro, escolhendo um ponto na fatia ABC. Novamente, estenda para ABCD, onde D é agora duas vezes o raio do centro do círculo.

    Escolher um ponto random no ABCD é fácil usando o método acima. Escolha um ponto random em AB. Escolha uniformemente um ponto random no BC. Ie. escolha um par de números randoms x e y uniformemente em [0, R] dando distâncias do centro. Nosso triângulo é uma fita fina, de modo que AB e BC são essencialmente paralelos. Então o ponto Z é simplesmente uma distância x + y da origem. Se x + y> R, dobramos novamente.

    Aqui está o algoritmo completo para R = 1. Eu espero que você concorde que é bem simples. Ele usa trigonometria, mas você pode dar uma garantia sobre quanto tempo levará e quantas chamadas random() ele precisa, ao contrário da amostragem de rejeição.

     t = 2*pi*random() u = random()+random() r = if u>1 then 2-u else u [r*cos(t), r*sin(t)] 

    Aqui está no Mathematica.

     f[] := Block[{u, t, r}, u = Random[] + Random[]; t = Random[] 2 Pi; r = If[u > 1, 2 - u, u]; {r Cos[t], r Sin[t]} ] ListPlot[Table[f[], {10000}], AspectRatio -> Automatic] 

    insira a descrição da imagem aqui

    Como gerar um ponto random dentro de um círculo de raio R :

     r = R * sqrt(random()) theta = random() * 2 * PI 

    (Assumindo random() dá um valor entre 0 e 1 uniformemente)

    Se você quiser converter isso em coordenadas cartesianas, você pode fazer

     x = r * cos(theta) y = r * sin(theta) 

    Por que sqrt(random()) ?

    Vamos ver a matemática que leva ao sqrt(random()) . Suponha, por simplicidade, que estamos trabalhando com o círculo unitário, ou seja, R = 1.

    A distância média entre os pontos deve ser a mesma, independentemente de quão longe do centro nós olhamos. Isso significa, por exemplo, que, olhando no perímetro de um círculo com a circunferência 2, devemos encontrar o dobro de pontos que o número de pontos no perímetro de um círculo com a circunferência 1.

    Como a circunferência de um círculo (2π r ) cresce linearmente com r , segue-se que o número de pontos randoms deve crescer linearmente com r . Em outras palavras, a function de densidade de probabilidade desejada (PDF) cresce linearmente. Como um PDF deve ter uma área igual a 1 e o raio máximo é 1, temos

    Portanto, sabemos como a densidade desejada de nossos valores randoms deve ser semelhante. Agora: Como geramos um valor tão random quando tudo o que temos é um valor random uniforme entre 0 e 1?

    Nós usamos um truque chamado amostragem de transformação inversa

    1. A partir do PDF, crie a function de distribuição cumulativa (CDF)
    2. Espelhe isso ao longo de y = x
    3. Aplique a function resultante a um valor uniforme entre 0 e 1.

    Soa complicado? Deixe-me inserir uma checkbox amarela com um pequeno desvio que transmite a intuição:

    Suponha que queremos gerar um ponto random com a seguinte distribuição:

    Isso é

    • 1/5 dos pontos uniformemente entre 1 e 2, e
    • 4/5 dos pontos uniformemente entre 2 e 3.

    O CDF é, como o nome sugere, a versão cumulativa do PDF. Intuitivamente: Enquanto PDF ( x ) descreve o número de valores randoms em x , CDF ( x ) descreve o número de valores randoms menores que x .

    Nesse caso, o CDF se pareceria com:

    Para ver como isso é útil, imagine que atiramos balas da esquerda para a direita em alturas uniformemente distribuídas. Quando as balas atingem a linha, elas caem no chão:

    Veja como a densidade das balas no solo corresponde à nossa distribuição desejada! Estamos quase lá!

    O problema é que, para esta function, o eixo y é a saída e o eixo x é a input . Nós só podemos “triggersr balas do chão para cima”! Nós precisamos da function inversa!

    É por isso que espelhamos a coisa toda; x torna-se y e y torna-se x :

    Nós chamamos isso de CDF -1 . Para obter valores de acordo com a distribuição desejada, usamos CDF -1 (random ()).

    … Então, voltando a gerar valores de raio randoms onde nosso PDF é igual a 2 x .

    Etapa 1: crie o CDF:

    Como estamos trabalhando com reais, o CDF é expresso como o integral do PDF.

    CDF ( x ) = ∫ 2 x = x 2

    Passo 2: Espelhe o CDF ao longo de y = x :

    Matematicamente isto resume-se a trocar x e y e resolver por y :

    CDF : y = x 2
    Troca: x = y 2
    Resolva: y = √ x
    CDF -1 : y = √ x

    Etapa 3: Aplique a function resultante a um valor uniforme entre 0 e 1

    CDF -1 (random ()) = random ()

    Qual é o que nos propusemos a derivar 🙂

    Aqui está uma solução rápida e simples.

    Escolha dois números randoms no intervalo (0, 1), ou seja, a e b . Se b < a , troque-os. Seu ponto é (b*R*cos(2*pi*a/b), b*R*sin(2*pi*a/b)) .

    Você pode pensar sobre essa solução da seguinte maneira. Se você pegasse o círculo, cortasse e depois endireitasse, você obteria um triângulo retângulo. Escale esse triângulo para baixo e você terá um triângulo de (0, 0) a (1, 0) a (1, 1) e vice-versa (0, 0) . Todas essas transformações alteram a densidade uniformemente. O que você fez foi escolher uniformemente um ponto random no triângulo e reverteu o processo para obter um ponto no círculo.

    Observe a densidade do ponto proporcional ao quadrado inverso do raio, portanto, em vez de escolher r de [0, r_max] , selecionar [0, r_max^2] , calcule suas coordenadas como:

     x = sqrt(r) * cos(angle) y = sqrt(r) * sin(angle) 

    Isso lhe dará distribuição uniforme de pontos em um disco.

    http://mathworld.wolfram.com/DiskPointPicking.html

    Pense nisso desta maneira. Se você tem um retângulo onde um eixo é raio e um é ângulo, e você pega os pontos dentro deste retângulo que estão próximos do raio 0. Eles ficarão todos muito próximos da origem (que estão próximos no círculo). os pontos próximos ao raio R, todos eles ficarão perto da borda do círculo (isto é, longe um do outro).

    Isso pode lhe dar uma idéia de por que você está recebendo esse comportamento.

    O fator que é derivado nesse link informa a quantidade de área correspondente no retângulo que precisa ser ajustada para não depender do raio, uma vez mapeado para o círculo.

    Edit: Então, o que ele escreve no link que você compartilha é: “Isso é bastante fácil de fazer, calculando o inverso da distribuição cumulativa, e obtemos para r:”.

    A premissa básica é aqui que você pode criar uma variável com uma distribuição desejada de um uniforme mapeando o uniforme pela function inversa da function de distribuição cumulativa da function de densidade de probabilidade desejada. Por quê? Apenas tome por certo por enquanto, mas isso é um fato.

    Aqui está minha explicação intuitiva da matemática. A function de densidade f (r) em relação a r tem que ser proporcional a r em si. Entender esse fato faz parte de qualquer livro de cálculo básico. Veja seções sobre elementos da área polar. Alguns outros cartazes mencionaram isso.

    Então vamos chamá-lo f (r) = C * r;

    Isso acaba sendo a maior parte do trabalho. Agora, como f (r) deve ser uma densidade de probabilidade, você pode ver facilmente que, ao integrar f (r) ao longo do intervalo (0, R), obtém-se C = 2 / R ^ 2 (este é um exercício para o leitor). .)

    Assim, f (r) = 2 * r / R ^ 2

    OK, então é assim que você obtém a fórmula no link.

    Então, a parte final está indo da variável aleatória uniforme u em (0,1) você deve mapear pela function inversa da function de distribuição cumulativa desta densidade desejada f (r). Para entender por que esse é o caso, você precisa encontrar um texto de probabilidade avançado como Papoulis provavelmente (ou derivar você mesmo).

    Integrando f (r) você obtém F (r) = r ^ 2 / R ^ 2

    Para encontrar a function inversa disto você ajusta u = r ^ 2 / R ^ 2 e então resolve para r, que lhe dá r = R * sqrt (u)

    Isso também faz sentido intuitivamente, u = 0 deve mapear para r = 0. Além disso, u = 1 shoudl map para r = R. Além disso, ele segue a function de raiz quadrada, que faz sentido e corresponde ao link.

    Isso realmente depende do que você entende por “uniformemente random”. Este é um ponto sutil e você pode ler mais sobre isso na página wiki aqui: http://en.wikipedia.org/wiki/Bertrand_paradox_%28probability%29 , onde o mesmo problema, dando interpretações diferentes a ‘uniformemente aleatórias’ dá respostas diferentes!

    Dependendo de como você escolhe os pontos, a distribuição pode variar, mesmo que eles sejam uniformemente randoms em algum sentido.

    Parece que a input do blog está tentando torná-la uniformemente aleatória no seguinte sentido: Se você pegar um subcírculo do círculo, com o mesmo centro, a probabilidade de o ponto cair nessa região é proporcional à área de a região. Isso, acredito, está tentando seguir a interpretação agora padrão de ‘uniformemente random’ para regiões 2D com áreas definidas nelas : a probabilidade de um ponto cair em qualquer região (com área bem definida) é proporcional à área daquela região.

    A razão pela qual a solução ingênua não funciona é que ela fornece uma densidade de probabilidade mais alta para os pontos mais próximos do centro do círculo. Em outras palavras, o círculo que tem raio r / 2 tem probabilidade r / 2 de obter um ponto selecionado, mas tem área (número de pontos) pi * r ^ 2/4.

    Portanto, queremos que uma densidade de probabilidade de raio tenha a seguinte propriedade:

    A probabilidade de escolher um raio menor ou igual a um dado r tem que ser proporcional à área do círculo com raio r. (porque queremos ter uma distribuição uniforme nos pontos e áreas maiores significam mais pontos)

    Em outras palavras, queremos que a probabilidade de escolher um raio entre [0, r] seja igual à sua parte da área total do círculo. A área total do círculo é pi * R ^ 2 e a área do círculo com raio r é pi * r ^ 2. Assim, gostaríamos que a probabilidade de escolher um raio entre [0, r] fosse (pi * r ^ 2) / (pi * R ^ 2) = r ^ 2 / R ^ 2.

    Agora vem a matemática:

    A probabilidade de escolher um raio entre [0, r] é a integral de p (r) dr de 0 a r (isso é apenas porque adicionamos todas as probabilidades dos raios menores). Assim, queremos integral (p (r) dr) = r ^ 2 / R ^ 2. Podemos ver claramente que R ^ 2 é uma constante, então tudo o que precisamos fazer é descobrir qual p (r), quando integrado, nos daria algo como r ^ 2. A resposta é claramente r * constante. integral (r * constante dr) = r ^ 2/2 * constante. Isto tem que ser igual a r ^ 2 / R ^ 2, portanto constante = 2 / R ^ 2. Assim você tem a distribuição de probabilidade p (r) = r * 2 / R ^ 2

    Nota: Outra maneira mais intuitiva de pensar sobre o problema é imaginar que você está tentando dar a cada círculo de raio uma densidade de probabilidade igual à proporção do número de pontos que ele tem em sua circunferência. Assim, um círculo que tenha raio r terá 2 * pi * r “pontos” em sua circunferência. O número total de pontos é pi * R ^ 2. Assim, você deve dar ao círculo ra probabilidade igual a (2 * pi * r) / (pi * R ^ 2) = 2 * r / R ^ 2. Isso é muito mais fácil de entender e mais intuitivo, mas não é tão matematicamente sólido.

    Aqui está o meu código Python para gerar um num de pontos randoms a partir de um círculo de rad :

     import matplotlib.pyplot as plt import numpy as np rad = 10 num = 1000 t = np.random.uniform(0.0, 2.0*np.pi, num) r = rad * np.sqrt(np.random.uniform(0.0, 1.0, num)) x = r * np.cos(t) y = r * np.sin(t) plt.plot(x, y, "ro", ms=1) plt.axis([-15, 15, -15, 15]) plt.show() 

    Seja ρ (raio) e φ (azimute) duas variables ​​aleatórias correspondentes a coordenadas polares de um ponto arbitrário dentro do círculo. Se os pontos são distribuídos uniformemente, então qual é a function de distribuição de ρ e φ?

    Para qualquer r: 0

    P [ρ 2

    Onde S1 e S0 são as áreas do círculo do raio r e R respectivamente. Então o CDF pode ser dado como:

      0 if r< =0 CDF = (r/R)**2 if 0 < r <= R 1 if r > R 

    E PDF:

     PDF = d/dr(CDF) = 2 * (r/R**2) (0 < r <= R). 

    Note que para R = 1 a variável aleatória sqrt (X) onde X é uniforme em [0, 1) tem essa CDF exata (porque P [sqrt (X)

    A distribuição de φ é obviamente uniforme de 0 a 2 * π. Agora você pode criar coordenadas polares aleatórias e convertê-las em cartesianas usando equações trigonométricas:

     x = ρ * cos(φ) y = ρ * sin(φ) 

    Não posso resistir a postar código python para R = 1.

     from matplotlib import pyplot as plt import numpy as np rho = np.sqrt(np.random.uniform(0, 1, 5000)) phi = np.random.uniform(0, 2*np.pi, 5000) x = rho * np.cos(phi) y = rho * np.sin(phi) plt.scatter(x, y, s = 4) 

    Você vai ter

    Solução em Java e o exemplo de distribuição (2000 pontos)

     public void getRandomPointInCircle() { double t = 2 * Math.PI * Math.random(); double r = Math.sqrt(Math.random()); double x = r * Math.cos(t); double y = r * Math.sin(t); System.out.println(x); System.out.println(y); } 

    Distribuição 2000 pontos

    com base na solução previus https://stackoverflow.com/a/5838055/5224246 da @sigfpe

    Eu acho que neste caso usando coordenadas polares é uma maneira de complicar o problema, seria muito mais fácil se você escolhesse pontos randoms em um quadrado com lados de comprimento 2R e então selecionasse os pontos (x,y) tal forma que x^2+y^2< =R^2 .

    Primeiro nós geramos um cdf [x] que é

    A probabilidade de que um ponto seja menor que a distância x do centro do círculo. Suponha que o círculo tenha um raio de R.

    obviamente, se x é zero, então cdf [0] = 0

    obviamente, se x é R, então o cdf [R] = 1

    obviamente, se x = r, então o cdf [r] = (Pi r ^ 2) / (Pi R ^ 2)

    Isso ocorre porque cada “área pequena” no círculo tem a mesma probabilidade de ser escolhida. Portanto, a probabilidade é proporcional à área em questão. E a área dada uma distância x do centro do círculo é Pi r ^ 2

    então cdf [x] = x ^ 2 / R ^ 2 porque o Pi se anulam

    temos cdf [x] = x ^ 2 / R ^ 2 onde x vai de 0 a R

    Então resolvemos para x

     R^2 cdf[x] = x^2 x = R Sqrt[ cdf[x] ] 

    Agora podemos replace o cdf por um número random de 0 a 1

     x = R Sqrt[ RandomReal[{0,1}] ] 

    Finalmente

     r = R Sqrt[ RandomReal[{0,1}] ]; theta = 360 deg * RandomReal[{0,1}]; {r,theta} 

    obtemos as coordenadas polares {0,601168 R, 311,915 graus}

    Existe uma relação linear entre o raio e o número de pontos “próximos” desse raio, então ele precisa usar uma distribuição de raio que também torna o número de pontos de dados próximo a um raio r proporcional a r .

    Eu usei uma vez esse método: Isso pode ser totalmente não otimizado (ou seja, ele usa uma matriz de pontos para que seja inutilizável para grandes círculos), mas fornece distribuição aleatória suficiente. Você pode pular a criação da matriz e desenhar diretamente, se desejar. O método é randomizar todos os pontos em um retângulo que caia dentro do círculo.

     bool[,] getMatrix(System.Drawing.Rectangle r) { bool[,] matrix = new bool[r.Width, r.Height]; return matrix; } void fillMatrix(ref bool[,] matrix, Vector center) { double radius = center.X; Random r = new Random(); for (int y = 0; y < matrix.GetLength(0); y++) { for (int x = 0; x < matrix.GetLength(1); x++) { double distance = (center - new Vector(x, y)).Length; if (distance < radius) { matrix[x, y] = r.NextDouble() > 0.5; } } } } private void drawMatrix(Vector centerPoint, double radius, bool[,] matrix) { var g = this.CreateGraphics(); Bitmap pixel = new Bitmap(1,1); pixel.SetPixel(0, 0, Color.Black); for (int y = 0; y < matrix.GetLength(0); y++) { for (int x = 0; x < matrix.GetLength(1); x++) { if (matrix[x, y]) { g.DrawImage(pixel, new PointF((float)(centerPoint.X - radius + x), (float)(centerPoint.Y - radius + y))); } } } g.Dispose(); } private void button1_Click(object sender, EventArgs e) { System.Drawing.Rectangle r = new System.Drawing.Rectangle(100,100,200,200); double radius = r.Width / 2; Vector center = new Vector(r.Left + radius, r.Top + radius); Vector normalizedCenter = new Vector(radius, radius); bool[,] matrix = getMatrix(r); fillMatrix(ref matrix, normalizedCenter); drawMatrix(center, radius, matrix); } 

    insira a descrição da imagem aqui

    O elemento de área em um círculo é dA = rdr * dphi. Esse fator extra destruiu sua ideia para escolher aleatoriamente ar e phi. Enquanto phi é distribuído flat, r não é, mas flat em 1 / r (ou seja, é mais provável que você atinja o limite do que “o bull’s eye”).

    Então, para gerar pontos distribuídos uniformemente sobre o círculo, escolha phi de uma distribuição plana e r de uma distribuição 1 / r.

    Como alternativa, use o método de Monte Carlo proposto por Mehrdad.

    EDITAR

    Para escolher um plano random em 1 / r, você poderia escolher um x random a partir do intervalo [1 / R, infinito] e calcular r = 1 / x. r é então distribuído flat em 1 / r.

    Para calcular um ph random, escolha um x random a partir do intervalo [0, 1] e calcule phi = 2 * pi * x.

    Eu não sei se esta questão ainda está aberta para uma nova solução com toda a resposta já dada, mas eu mesmo já enfrentei exatamente a mesma pergunta. Eu tentei “raciocinar” comigo mesmo por uma solução, e encontrei uma. Pode ser a mesma coisa que alguns já sugeriram aqui, mas de qualquer forma aqui está:

    para que dois elementos da superfície do círculo sejam iguais, assumindo drs iguais, devemos ter dtheta1 / dtheta2 = r2 / r1. Escrevendo a expressão da probabilidade para aquele elemento como P (r, teta) = P {r1

    Uma solução de programador:

    • Crie um mapa de bits (uma matriz de valores booleanos). Pode ser tão grande quanto você quiser.
    • Desenhe um círculo nesse mapa de bits.
    • Crie uma tabela de pesquisa dos pontos do círculo.
    • Escolha um índice random nesta tabela de pesquisa.
     const int RADIUS = 64; const int MATRIX_SIZE = RADIUS * 2; bool matrix[MATRIX_SIZE][MATRIX_SIZE] = {0}; struct Point { int x; int y; }; Point lookupTable[MATRIX_SIZE * MATRIX_SIZE]; void init() { int numberOfOnBits = 0; for (int x = 0 ; x < MATRIX_SIZE ; ++x) { for (int y = 0 ; y < MATRIX_SIZE ; ++y) { if (x * x + y * y < RADIUS * RADIUS) { matrix[x][y] = true; loopUpTable[numberOfOnBits].x = x; loopUpTable[numberOfOnBits].y = y; ++numberOfOnBits; } // if } // for } // for } // () Point choose() { int randomIndex = randomInt(numberOfBits); return loopUpTable[randomIndex]; } // () 

    O bitmap é necessário apenas para a explicação da lógica. Este é o código sem o bitmap:

     const int RADIUS = 64; const int MATRIX_SIZE = RADIUS * 2; struct Point { int x; int y; }; Point lookupTable[MATRIX_SIZE * MATRIX_SIZE]; void init() { int numberOfOnBits = 0; for (int x = 0 ; x < MATRIX_SIZE ; ++x) { for (int y = 0 ; y < MATRIX_SIZE ; ++y) { if (x * x + y * y < RADIUS * RADIUS) { loopUpTable[numberOfOnBits].x = x; loopUpTable[numberOfOnBits].y = y; ++numberOfOnBits; } // if } // for } // for } // () Point choose() { int randomIndex = randomInt(numberOfBits); return loopUpTable[randomIndex]; } // () 

    Eu ainda não tenho certeza sobre o ‘(2 / R2) × r’ exato, mas o que é aparente é o número de pontos requeridos para ser distribuído em dada unidade ‘dr’, isto é, o aumento em r será proporcional a r2 e não r.

    verifique desta forma … número de pontos em algum ângulo teta e entre r (0.1r a 0.2r) ie fração do re número de pontos entre r (0.6r a 0.7r) seria igual se você usar geração padrão, já que a diferença é de apenas 0,1r entre dois intervalos. mas como a área coberta entre os pontos (0,6r a 0,7r) será muito maior que a área coberta entre 0,1r e 0,2r, o número igual de pontos será esparsamente espaçado em uma área maior, isso eu suponho que você já saiba, então a function para gerar os pontos randoms não deve ser linear mas sim quadrático, (já que o número de pontos requeridos para ser distribuído na dada unidade ‘dr’, isto é, o aumento em r será proporcional a r2 e não r), então neste caso será inverso de quadrático, uma vez que o delta que temos (0.1r) em ambos os intervalos deve ser quadrado de alguma function para que ele possa atuar como valor de semente para geração linear de pontos (pois depois, esta semente é usada linearmente em sin e cos function), então sabe, dr deve ser um valor quadrático e para fazer essa semente quadrática, precisamos originar esses valores da raiz quadrada do próprio r não, espero que isso torne isso pouco mais claro.

    Um problema tão divertido.
    A lógica da probabilidade de um ponto ser escolhido diminuindo à medida que a distância da origem do eixo aumenta é explicada várias vezes acima. Nós contabilizamos isso pegando a raiz de U [0,1]. Aqui está uma solução geral para um r positivo no Python 3.

     import numpy import math import matplotlib.pyplot as plt def sq_point_in_circle(r): """ Generate a random point in an r radius circle centered around the start of the axis """ t = 2*math.pi*numpy.random.uniform() R = (numpy.random.uniform(0,1) ** 0.5) * r return(R*math.cos(t), R*math.sin(t)) R = 200 # Radius N = 1000 # Samples points = numpy.array([sq_point_in_circle(R) for i in range(N)]) plt.scatter(points[:, 0], points[:,1]) 

    insira a descrição da imagem aqui

    Você também pode usar sua intuição.

    A área de um círculo é pi*r^2

    Para r=1

    Isso nos dá uma área de pi . Vamos supor que tenhamos algum tipo de function que uniformemente distribuiria N=10 pontos dentro de um círculo. A proporção aqui é 10 / pi

    Agora nós dobramos a área e o número de pontos

    Para r=2 e N=20

    Isto dá uma área de 4pi e a relação é agora 20/4pi ou 10/2pi . A proporção será menor e menor quanto maior for o raio, porque o seu crescimento é quadrático e o N escala linearmente.

    Para consertar isso, podemos apenas dizer

     x = r^2 sqrt(x) = r 

    Se você gerasse um vetor em coordenadas polares como esta

     length = random_0_1(); angle = random_0_2pi(); 

    Mais pontos aterrissariam ao redor do centro.

     length = sqrt(random_0_1()); angle = random_0_2pi(); 

    length não é mais uniformemente distribuído, mas o vetor agora será uniformemente distribuído.

    1) Escolha um X random entre -1 e 1.

     var X:Number = Math.random() * 2 - 1; 

    2) Usando a fórmula do círculo, calcule os valores máximo e mínimo de Y, dado que X e um raio de 1:

     var YMin:Number = -Math.sqrt(1 - X * X); var YMax:Number = Math.sqrt(1 - X * X); 

    3) Escolha um Y random entre esses extremos:

     var Y:Number = Math.random() * (YMax - YMin) + YMin; 

    4) Incorpore seus valores de localização e raio no valor final:

     var finalX:Number = X * radius + pos.x; var finalY:Number = Y * radois + pos.y;