web-dev-qa-db-fra.com

Générer un point aléatoire dans un cercle (uniformément)

J'ai besoin de générer un point uniformément aléatoire dans un cercle de rayon R.

Je réalise qu'en choisissant un angle uniformément aléatoire dans l'intervalle [0 ... 2π) et un rayon uniformément aléatoire dans l'intervalle (0 ... _ {R], je me retrouverais avec plus de points vers le centre, puisque pour deux rayons donnés, les points du rayon le plus petit seront plus proches les uns des autres que ceux du rayon le plus grand.

J'ai trouvé une entrée de blog à ce sujet ici mais je ne comprends pas son raisonnement. Je suppose que c'est correct, mais j'aimerais vraiment comprendre d'où il vient (2/R2) × (r} _ et comment il en tire la solution finale.


Mise à jour: Sept ans après la publication de cette question, je n’avais toujours pas reçu de réponse satisfaisante à la question concernant le calcul derrière l’algorithme de racine carrée. J'ai donc passé une journée à rédiger moi-même une réponse. Lien vers ma réponse .

178
aioobe

Comment générer un point aléatoire dans un cercle de rayon R:

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

(En supposant que random() donne une valeur comprise entre 0 et 1 uniformément)

Si vous voulez convertir ceci en coordonnées cartésiennes, vous pouvez faire

x = centerX + r * cos(theta)
y = centerY + r * sin(theta)


Pourquoi sqrt(random())?

Regardons les calculs qui mènent à sqrt(random()). Supposons, pour simplifier, que nous travaillons avec le cercle unitaire, c'est-à-dire R = 1.

La distance moyenne entre les points devrait être la même quelle que soit la distance à laquelle nous nous rapprochons du centre. Cela signifie, par exemple, que pour chercher sur le périmètre d'un cercle de circonférence 2, nous devrions trouver deux fois plus de points que de nombre de points sur le périmètre d'un cercle de circonférence 1.




Depuis la circonférence d'un cercle (2πr) croît linéairement avec r, il en résulte que le nombre de points aléatoires devrait croître linéairement avec r. En d’autres termes, la fonction de densité de probabilité } (PDF) souhaitée croît de manière linéaire. Comme un PDF doit avoir une surface égale à 1 et un rayon maximal de 1, nous avons


Nous savons donc à quoi devrait ressembler la densité souhaitée de nos valeurs aléatoires . Maintenant: Comment génère-t-on une telle valeur aléatoire alors que tout ce dont nous disposons est une valeur aléatoire uniforme comprise entre 0 et 1?

Nous utilisons une astuce appelée échantillonnage par transformée inverse

  1. A partir du PDF, créez la fonction de distribution cumulative _ (CDF)
  2. Refléter ceci le long de y = x
  3. Appliquez la fonction résultante à une valeur uniforme comprise entre 0 et 1.

Cela semble compliqué? Permettez-moi d'insérer une boîte jaune avec une petite déviation qui traduit l'intuition:

Supposons que nous voulions générer un point aléatoire avec la distribution suivante:

C'est

  • 1/5 des points uniformément compris entre 1 et 2, et
  • 4/5 des points uniformément entre 2 et 3.

Le CDF est, comme son nom l’indique, la version cumulative du PDF. Intuitivement: alors que PDF (x) décrit le nombre de valeurs aléatoires à x, CDF (x) décrit le nombre de valeurs aléatoires inférieur à x.

Dans ce cas, le CDF ressemblerait à ceci:

Pour voir à quel point cela est utile, imaginons que nous tirions des balles de gauche à droite à des hauteurs uniformément réparties. Lorsque les balles touchent la ligne de front, elles tombent au sol:

Voyez comment la densité des balles au sol correspond à notre répartition souhaitée! Nous y sommes presque!

Le problème est que pour cette fonction, l'axe y est l'axe sortie et l'axe x est l'axe entrée. Nous ne pouvons que "tirer des balles depuis le sol"! Nous avons besoin de la fonction inverse!

C'est pourquoi nous reflétons le tout; x devient y et y devient x:

Nous appelons cela CDF-1 Pour obtenir des valeurs en fonction de la distribution souhaitée, nous utilisons CDF-1(au hasard()).

… Donc, retour à la génération de valeurs de rayon aléatoires où notre PDF est égal à 2x.

Étape 1: Créez le CDF:

Puisque nous travaillons avec des réels, le CDF est exprimé comme l’intégrale du PDF.

CDF(x) = ∫ 2xx2

Étape 2: dupliquez le CDF en miroir le long de y = x

Mathématiquement, cela revient à échanger x et y et à résoudre pour y:

CDF: Yx2
Échange: xy2
Résoudre: y = √x
CDF-1: Y = √x

Étape 3: Applique la fonction résultante à une valeur uniforme comprise entre 0 et 1

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

Quel est ce que nous avons cherché à dériver :-)

57
aioobe

Abordons cela comme Archimède l'aurait fait.

Comment pouvons-nous générer un point uniformément dans un triangle ABC, où | AB | = | BC |? Rendons cela plus facile en développant un parallélogramme ABCD. Il est facile de générer des points de manière uniforme dans ABCD. Nous choisissons uniformément un point aléatoire X sur AB et Y sur BC et choisissons Z tel que XBYZ soit un parallélogramme. Pour obtenir un point choisi uniformément dans le triangle d'origine, il suffit de replier tous les points apparaissant dans ADC vers ABC le long de AC.

Considérons maintenant un cercle. À la limite, on peut penser qu’il existe une infinité de triangles isocèles ABC avec B à l’origine et A et C sur la circonférence se rapprochant de plus en plus. Nous pouvons choisir l'un de ces triangles simplement en choisissant un angle thêta. Il nous faut donc maintenant générer une distance par rapport au centre en choisissant un point dans le ruban ABC. Encore une fois, étendre à ABCD, où D est maintenant deux fois le rayon du centre du cercle.

Choisir un point aléatoire dans ABCD est facile en utilisant la méthode ci-dessus. Choisissez un point aléatoire sur AB. Choisissez uniformément un point aléatoire sur BC. C'est à dire. choisissez une paire de nombres aléatoires x et y uniformément sur [0, R] en donnant les distances du centre. Notre triangle est un mince ruban, de sorte que AB et BC sont essentiellement parallèles. Donc, le point Z est simplement une distance x + y de l'origine. Si x + y> R, nous nous rabattons.

Voici l'algorithme complet pour R = 1. J'espère que vous êtes d'accord, c'est assez simple. Il utilise trig, mais vous pouvez donner une garantie sur sa durée et le nombre d'appels random() dont il a besoin, contrairement à l'échantillonnage de rejet.

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

Le voici dans 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]

enter image description here

180
sigfpe

Voici une solution simple et rapide.

Choisissez deux nombres aléatoires dans l'intervalle (0, 1), à savoir a et b. Si b < a, échangez-les. Votre point est (b*R*cos(2*pi*a/b), b*R*sin(2*pi*a/b)).

Vous pouvez penser à cette solution comme suit. Si vous preniez le cercle, coupez-le puis redressez-le, vous obtiendrez un triangle rectangle. Réduisez l'échelle de ce triangle et vous obtiendrez un triangle de (0, 0) à (1, 0) à (1, 1) et inversement à (0, 0). Toutes ces transformations changent la densité uniformément. Ce que vous avez fait est uniformément choisi un point au hasard dans le triangle et inversé le processus pour obtenir un point dans le cercle.

26
btilly

Notez la densité de points proportionnelle au carré inverse du rayon, par conséquent, au lieu de sélectionner r dans [0, r_max], choisissez dans [0, r_max^2], puis calculez vos coordonnées comme suit:

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

Cela vous donnera une distribution de points uniforme sur un disque.

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

18
Libor

Pensez-y de cette façon. Si vous avez un rectangle où l'un des axes est rayon et l'autre angle, et que vous prenez les points à l'intérieur de ce rectangle qui sont proches du rayon 0, ils tomberont tous très près de l'origine (qui est proche l'un de l'autre sur le cercle.) les points proches du rayon R, ils tomberont tous près du bord du cercle (c’est-à-dire très éloignés les uns des autres). 

Cela pourrait vous donner une idée de la raison pour laquelle vous obtenez ce comportement.

Le facteur qui est dérivé sur ce lien vous indique combien de zones correspondantes dans le rectangle doivent être ajustées pour ne pas dépendre du rayon une fois qu'elles sont mappées au cercle.

Edit: Ainsi, dans le lien que vous partagez, il écrit: "C’est assez facile à faire en calculant l’inverse de la distribution cumulative, et on obtient pour r:".

Le principe de base est que vous pouvez créer une variable avec une distribution souhaitée à partir d’un uniforme en mappant l’uniforme par la fonction inverse de la fonction de distribution cumulative de la fonction de densité de probabilité souhaitée. Pourquoi? Prenez cela pour acquis pour le moment, mais c’est un fait.

Voici mon explication intuitive des maths. La fonction de densité f(r) par rapport à r doit être proportionnelle à r elle-même. Comprendre ce fait fait partie de tout livre de calcul de base. Voir les sections sur les éléments de la zone polaire. Certaines autres affiches ont mentionné cela. 

Nous allons donc l'appeler f(r) = C * r; 

Cela s'avère être la majeure partie du travail. Maintenant, puisque f(r) doit être une densité de probabilité, vous pouvez facilement voir qu'en intégrant f(r) sur l'intervalle (0, R), vous obtenez que C = 2/R ^ 2 (Ceci est un exercice pour le lecteur.) 

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

OK, c'est comme ça que vous obtenez la formule dans le lien. 

Ensuite, la dernière partie part de la variable aléatoire uniforme u in (0,1) que vous devez mapper par la fonction inverse de la fonction de distribution cumulée à partir de cette densité souhaitée f (r). Pour comprendre pourquoi c'est le cas, vous devez probablement trouver un texte de probabilité avancée tel que Papoulis (ou le créer vous-même).

En intégrant f(r) vous obtenez F(r) = r ^ 2/R ^ 2

Pour trouver la fonction inverse de ceci, définissez u = r ^ 2/R ^ 2, puis résolvez pour r, ce qui vous donne r = R * sqrt (u)

Cela a également un sens intuitif aussi, u = 0 devrait correspondre à r = 0. En outre, u = 1 devrait mapper à r = R. Il dépend également de la fonction racine carrée, ce qui a un sens et correspond au lien.

12
Chris A.

La solution naïve ne fonctionne pas parce qu’elle donne une densité de probabilité plus élevée aux points les plus proches du centre du cercle. En d’autres termes, le cercle de rayon r/2 a la probabilité r/2 d’obtenir un point sélectionné, mais il a une surface (nombre de points) pi * r ^ 2/4.

Par conséquent, nous souhaitons qu'une densité de probabilité de rayon ait la propriété suivante: 

La probabilité de choisir un rayon inférieur ou égal à un r donné doit être proportionnelle à l'aire du cercle de rayon r. (parce que nous voulons avoir une distribution uniforme sur les points et que des zones plus grandes signifient plus de points)

En d'autres termes, nous voulons que la probabilité de choisir un rayon entre [0, r] soit égale à sa part dans l'aire totale du cercle. L'aire du cercle total est pi * R ^ 2 et l'aire du cercle de rayon r est pi * r ^ 2. Nous voudrions donc que la probabilité de choisir un rayon entre [0, r] soit (pi * r ^ 2)/(pi * R ^ 2) = r ^ 2/R ^ 2.

Maintenant vient le calcul: 

La probabilité de choisir un rayon entre [0, r] est l'intégrale de p(r) dr de 0 à r (c'est simplement parce que nous ajoutons toutes les probabilités des plus petits rayons). Nous voulons donc une intégrale (p (r) dr) = r ^ 2/R ^ 2. Nous pouvons clairement voir que R ^ 2 est une constante. Il suffit donc de déterminer quel p (r), quand intégré, nous donnerait quelque chose comme r ^ 2. La réponse est clairement r * constante. intégrale (r * constante dr) = r ^ 2/2 * constante. Cela doit être égal à r ^ 2/R ^ 2, donc constant = 2/R ^ 2. Vous avez donc la distribution de probabilité p(r) = r * 2/R ^ 2

Remarque: Une autre façon plus intuitive de penser au problème consiste à imaginer que vous essayez de donner à chaque cercle de rayon r une densité de probabilité égale à la proportion du nombre de points qu'il a sur sa circonférence. Ainsi, un cercle de rayon r aura 2 * pi * r "points" sur sa circonférence. Le nombre total de points est pi * R ^ 2. Ainsi, vous devriez donner au cercle r une probabilité égale à (2 * pi * r)/(pi * R ^ 2) = 2 * r/R ^ 2. C’est beaucoup plus facile à comprendre et plus intuitif, mais ce n’est pas aussi mathématiquement valable.

8
user502248

Cela dépend vraiment de ce que vous entendez par «uniformément aléatoire». C'est un point subtil et vous pouvez en lire plus à ce sujet sur la page du wiki ici: http://en.wikipedia.org/wiki/Bertrand_paradox_%28probability%29 , où le même problème donne des interprétations différentes de ' uniformément aléatoire 'donne des réponses différentes!

Selon la manière dont vous choisissez les points, la distribution peut varier, même s'ils sont uniformément aléatoires au sens de {certains}.

Il semble que l’entrée de blog tente de la rendre uniformément aléatoire dans le sens suivant: si vous prenez un sous-cercle du cercle, avec le même centre, alors la probabilité que le point tombe dans cette région est proportionnelle à la surface de la région. Cela, je pense, tente de suivre l'interprétation désormais standard de "uniformément aléatoire" pour les régions 2D avec les zones définies sur celles-ci : la probabilité qu'un point tombe dans une région (avec une zone bien définie) est proportionnelle à la zone de cette région.

7
Aryabhatta

Soit ρ (rayon) et φ (azimut) deux variables aléatoires correspondant aux coordonnées polaires d'un point arbitraire à l'intérieur du cercle. Si les points sont uniformément répartis, quelle est la fonction de répartition de ρ et?

Pour tout r: 0 <r <R, la probabilité que la coordonnée du rayon ρ soit inférieure à r est

P [ρ <r] = P [le point est dans un cercle de rayon r] = S1/S0 = (r/R)2

Où S1 et S0 sont les aires de cercle de rayon r et R respectivement . On peut donc donner le CDF comme suit:

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

Et PDF:

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

Notez que pour R = 1 variable aléatoire sqrt (X) où X est uniforme sur [0, 1) a exactement ce CDF (car P [sqrt (X) <y] = P [x <y ** 2] = y * * 2 pour 0 <y <= 1). 

La distribution de φ est évidemment uniforme de 0 à 2 * π. Vous pouvez maintenant créer des coordonnées polaires aléatoires et les convertir en cartésien à l'aide d'équations trigonométriques:

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

Ne peut pas résister à poster du code python pour 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)

Tu auras

6
Pommy

Voici mon code Python pour générer num points aléatoires à partir d'un cercle de rayon 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()
5
krishnab

Je pense que dans ce cas, utiliser des coordonnées polaires est un moyen de compliquer le problème. Il serait beaucoup plus facile de choisir des points aléatoires dans un carré de côtés de longueur 2R, puis de sélectionner les points (x,y) tels que x^2+y^2<=R^2.

3
ascanio

Solution en Java et exemple de distribution (2000 points) 

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);
}

 Distribution 2000 points

basé sur la solution previus https://stackoverflow.com/a/5838055/5224246 de @sigfpe

3
bolec_kolec

Nous générons d’abord un cdf [x] qui est

Probabilité qu'un point soit inférieur à la distance x du centre du cercle. Supposons que le cercle a un rayon de R.

évidemment si x est zéro alors cdf [0] = 0

évidemment si x est R alors le cdf [R] = 1

évidemment si x = r alors le cdf [r] = (Pi r ^ 2)/(Pi R ^ 2)

En effet, chaque "petite zone" du cercle a la même probabilité d'être choisie. La probabilité est donc proportionnelle à la zone en question. Et l'aire donnée à une distance x du centre du cercle est Pi r ^ 2

alors cdf [x] = x ^ 2/R ^ 2 parce que les Pi s'annulent

nous avons cdf [x] = x ^ 2/R ^ 2 où x va de 0 à R

Nous résolvons donc pour x

R^2 cdf[x] = x^2

x = R Sqrt[ cdf[x] ]

Nous pouvons maintenant remplacer cdf par un nombre aléatoire de 0 à 1

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

Finalement

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

nous obtenons les coordonnées polaires {0.601168 R, 311.915 deg}

2
Steven Siew

Il existe une relation linéaire entre le rayon et le nombre de points "proches" de ce rayon. Il doit donc utiliser une distribution de rayon qui rend également le nombre de points de données proches d'un rayon r proportionnel à r.

1
recursive

J'ai utilisé une fois cette méthode: Vous pouvez ignorer la création de la matrice et dessiner directement si vous le souhaitez. La méthode consiste à randomiser tous les points d'un rectangle situés à l'intérieur du cercle.

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);
}

enter image description here

1
Marino Šimić

L'élément de surface dans un cercle est dA = rdr * dphi. Ce facteur supplémentaire r a détruit votre idée de choisir au hasard un r et un phi. Alors que phi est distribué à plat, r n’est pas, mais à plat dans 1/r (c’est-à-dire que vous avez plus de chances d’atteindre la limite que "la cible").

Donc, pour générer des points également répartis sur le cercle, choisissez phi dans une distribution plate et r dans une distribution 1/r.

Vous pouvez également utiliser la méthode de Monte Carlo proposée par Mehrdad.

MODIFIER

Pour choisir un r flat aléatoire dans 1/r, vous pouvez choisir un x aléatoire dans l'intervalle [1/R, infini] et calculer r = 1/x. r est ensuite distribué à plat dans 1/r.

Pour calculer un phi aléatoire, choisissez un x aléatoire dans l'intervalle [0, 1] et calculez phi = 2 * pi * x.

1
Benjamin Bannier

Une solution de programmeur:

  • Créez un bitmap (une matrice de valeurs booléennes). Il peut être aussi grand que vous le souhaitez.
  • Tracez un cercle dans cette carte de bits.
  • Créez une table de recherche des points du cercle.
  • Choisissez un index aléatoire dans cette table de recherche.
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];
} // ()

Le bitmap n'est nécessaire que pour expliquer la logique. C'est le code sans le 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];
} // ()
0
selalerer

Vous pouvez également utiliser votre intuition.

L'aire d'un cercle est pi*r^2

Pour r=1

Cela nous donne une superficie de pi. Supposons que nous ayons une sorte de fonction f qui dérouterait uniformément N=10 dans un cercle. Le rapport ici est 10 / pi

Maintenant nous doublons la surface et le nombre de points

Pour r=2 et N=20

Cela donne une aire de 4pi et le rapport est maintenant 20/4pi ou 10/2pi. Plus le rayon est grand, plus le rapport devient petit et petit, car sa croissance est quadratique et N est linéaire.

Pour résoudre ce problème, nous pouvons simplement dire

x = r^2
sqrt(x) = r

Si vous voulez générer un vecteur en coordonnées polaires comme ceci

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

Plus de points atterriraient autour du centre.

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

length n'est plus uniformément distribué, mais le vecteur sera maintenant uniformément distribué.

0
Maik Klein

Je ne suis toujours pas sûr de la précision '(2/R2) × r', mais il est évident que le nombre de points devant être répartis dans l'unité donnée 'dr', c'est-à-dire que l'augmentation de r sera proportionnelle à r2 et non à r. 

vérifiez de cette façon ... le nombre de points à un angle thêta compris entre r (0.1r à 0.2r), c’est-à-dire que la fraction de r et le nombre de points entre r (0.6r à 0.7r) serait égal si vous utilisez la génération standard, puisque la différence est seulement 0.1r entre deux intervalles. mais comme la surface couverte entre les points (0.6r à 0.7r) sera beaucoup plus grande que celle couverte entre 0.1r à 0.2r, le même nombre de points sera peu espacé dans une plus grande surface, je suppose que vous le savez déjà, donc la fonction pour générer les points aléatoires ne doit pas être linéaire mais quadratique (puisque le nombre de points devant être répartis dans l'unité donnée «dr», c’est-à-dire que l’augmentation de r sera proportionnelle à r2 et non r), de sorte que dans ce cas, il sera inverse de quadratique, puisque le delta que nous avons (0.1r) dans les deux intervalles doit être carré d'une fonction pour pouvoir servir de valeur de départ pour la génération linéaire de points (puisque les mots suivants, cette valeur initiale est utilisée de manière linéaire dans les fonctions sin et cos), sais, dr doit avoir une valeur quadratique et pour que cette graine soit quadratique, nous devons créer ces valeurs à partir de la racine carrée de r non r lui-même, j’espère que cela la rend un peu plus claire.

0
cheesefest

Je ne sais pas si cette question reste ouverte pour une nouvelle solution avec toutes les réponses déjà données, mais je me suis trouvé confronté exactement à la même question. J'ai essayé de «raisonner» avec moi-même pour trouver une solution et j'en ai trouvé une. C'est peut-être la même chose que certains l'ont déjà suggéré ici, mais en tout cas, voici: 

pour que deux éléments de la surface du cercle soient égaux, en supposant des dr égaux, nous devons avoir dtheta1/dtheta2 = r2/r1. Expression écrite de la probabilité pour cet élément sous la forme P (r, thêta) = P {r1 <r1 + dr, thêta1 <thêta <thêta + dtheta1} = f (r, thêta) * dr * dtheta1, et réglage des deux probabilités égales (pour r1 et r2), on arrive à (en supposant que r et thêta sont indépendants) f (r1)/r1 = f (r2)/r2 = constant, ce qui donne f(r) = c * r . Et le reste, déterminer la constante c découle de la condition sur laquelle f(r) est un PDF.

0
arsaKasra

Un tel problème amusant.
La logique de la probabilité qu’un point soit choisi diminuant à mesure que la distance à l’origine augmente augmente est expliquée plusieurs fois ci-dessus. Nous en tenons compte en prenant la racine de U [0,1] . Voici une solution générale pour un r positif dans 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])

 enter image description here

0
AChervony