2010-04-20 26 views
6

Je souhaite générer aléatoirement et uniformément des points sur un cylindre et un cône (séparément). Le cylindre est défini par son centre, son rayon et sa hauteur. Mêmes spécifications pour le cône. Je suis en mesure d'obtenir la boîte de délimitation pour chaque forme de sorte que je pensais à générer des points dans la boîte de délimitation. Cependant, je ne suis pas sûr de savoir comment les projeter sur le cylindre/cône ou si c'est la meilleure idée.Génération uniforme de points 3D sur cylindre/cône

Des suggestions?

Merci.

+1

On dirait que le ratio passe de 1,5 à 0,5. Vous voulez probablement ratio = (max_y-y)/cône-> Height() à la place. – comingstorm

+1

Aussi, pour empêcher vos points de se regrouper autour de l'apex, vous voulez y = (max_y-min_y) * (1-sqrt (RandomNumber())) + min_y – comingstorm

+0

ressemble à la question dans votre EDIT a été répondu. Pouvez-vous le nettoyer ou ajouter un autre EDIT pour indiquer qu'il a été répondu? – brainjam

Répondre

4

Le boîtier du cylindre est trivial. Si le cylindre de rayon r> 0 et la hauteur h> 0 est l'image de (x, y, z) = (r cos φ, r sin φ, z) sur φ ∈ [0, 2π [et z ∈ [-h/2, h/2], alors choisissez simplement φ et z de façon aléatoire sur ces intervalles. Bien sûr, on peut simplement paramétrer le cône en utilisant le paramétrage standard, mais alors l'élément surfacique ne sera pas constant sur le plan des paramètres, et donc la distribution des points ne sera pas aléatoire. Vous devez donc trouver un paramétrage différent. J'ai discuté ce sujet en détail pour une sphère à my AlgoSim site.

2

Il serait plus simple de générer les points directement sur le cylindre ou le cône.

Cela fait un moment que je l'ai fait, mais paramétrer l'axe du cylindre et ensuite pour chaque point paramétrer le cercle à cette hauteur. Cela va créer des points sur la surface. Le rayon du cercle est le rayon du cylindre.

Pour le cône, vous devez réduire le rayon du cercle lorsque vous passez de la base à l'apex.

-1

Pour mettre ces réponses en pseudo-code:

Pour un cylindre, étant donné cylinderRadius et cylinderHeight:

angle = random number between 0 & 360 

x = cos(pi/180*angle)*cylinderRadius 
y = sin(pi/180*angle)*cylinderRadius 
z = random number between 0 and cylinderHeight. 

Pour un cône, étant donné coneRadius, coneHeight:

angle = random number between 0 & 360 

z = random number between 0 and coneHeight 

thisRadius = coneRadius * (1-(z/coneHeight)); //This gives a decreasing radius as height increases. 

x = cos(pi/180*angle)*thisRadius 
y = sin(pi/180*angle)*thisRadius 

point (x, y, z) reposera sur le cylindre/cône. Générer assez de ces points et vous pouvez générer des particules sur la surface d'un cylindre/cône, mais il peut ne pas faire une distribution exactement uniforme ...

+0

Le problème * est * de trouver une distribution uniforme, et ce n'est pas le cas dans votre code pour le cône. –

2

Une façon de penser à cela est que le cylindre et le cône peuvent Déballez-les sur des surfaces planes - coupez-les simplement avec une ligne droite de haut en bas. Le cylindre se déroule dans un rectangle (si vous incluez le haut et le bas, ajoutez deux disques).

Le cône se déploie vers un triangle dont le fond incurvé correspond à l'arc de cercle (si vous incluez la base du cône, ajoutez un disque).

Il est assez facile d'incorporer ces surfaces planes à l'intérieur d'un rectangle R dans le plan xy. Générez des points uniformément répartis dans R et, lorsqu'ils se trouvent à l'intérieur des surfaces planes, associez-les aux surfaces d'origine. Faites attention aux autres réponses qui tentent de coordonner un cône en termes d'angle et de hauteur. Bien que les points soient distribués uniformément en ce qui concerne l'angle et la hauteur, ils ne seront pas distribués uniformément. région. Ils seront plus densément répartis à la pointe.

0

Soit un point être défini par des coordonnées r, un, h, où r est le "rayon" (distance de l'axe vertical passant du centre), un est l'angle comme en coordonnées polaires, et h est sa hauteur.

Pour le cylindre (rayon R et la hauteur H): choisir indépendamment

  • un uniforme dans [0, 2 pi),
  • h uniforme dans [0 , H], et
  • avec une "densité triangulaire": f (r) = 2 r/R si 0 < = r < = R, 0 sinon (la masse volumique à r doit être proportionnelle à la longueur de la circonférence du rayon r).

Il ne devrait pas être difficile de l'échantillon de cette distribution triangulaire, depuis sa distribution cumulative (un monôme quadratique) est facilement inversible (voir this article). En outre, cette réponse est basée sur l'intuition, mais il ne devrait pas être difficile de prouver que la distribution que vous obtenez sur le cylindre est uniforme.

pour le cône (rayon R et la hauteur H): choisir

  • un uniforme dans [0, 2 pi),
  • h avec une densité à base de un segment de parabole: f (h) = 3 (H - h)^2/H^3 si 0 < = h < = H, 0 sinon (la masse volumique à h devrait être proportionnelle à la surface de la section circulaire à la hauteur h),
  • laisser r (h) = (h -h) R/h (le rayon de la section à la hauteur h); puis choisir r avec un f "distribution triangulaire" (r) = 2 r/r (h) si 0 < = r < = r (h), 0 autrement.

Encore une fois, l'échantillonnage h devrait être facile, car la distribution cumulée est facilement inversible.

EDIT. Si vous voulez dire pour générer des points sur la surface des formes, la solution est plus simple:

Cylindre: choisir

  • un uniforme dans [0, 2 pi),
  • h uniforme dans [0, h],
  • r =R.

Cone: choisir

  • uniforme dans [0, 2 pi),
  • h avec une densité triangulaire: f (h) = 2 (H - h)/H^2 si 0 < = h < = H, 0 sinon (la masse volumique à h devrait être proportionnelle à la longueur de la circonférence à une hauteur h ).
  • r =r (h) = (H -h) R/H = rayon à la hauteur h .
+0

Je pense qu'il veut des points * sur * le cylindre, pas à l'intérieur. –

+0

Oups. Tu veux dire en surface? –

+0

Oui, par définition, un cylindre (et un cône) est une surface dans l'espace, pas un objet solide. Et je pense que l'OP utilise effectivement cette définition mathématique, parce qu'il utilise la préposition "on" plutôt que "inside". –

-1

Pour les points uniformes sur un cercle ou d'un cône de rayon R et hauteur/élévation H:

generate: 
    angle= uniform_random(0,2*pi) 
    value= uniform_random(0,1) 

in either case, let: 
    r= R * sqrt(value) 

then (using separate random numbers for each): 
    circle_point= point3d(r*cos(angle), r*sin(angle), H) 
or: 
    cone_point= point3d(r*cos(angle), r*sin(angle), r*H) 

Notez que si vous voulez une base sur votre cône, vous devrez le faire séparément la forme incurvée. Pour s'assurer que la densité des points est la même pour les différentes parties, il est facile de calculer les surfaces des parties et de générer un nombre proportionnel de points pour chaque partie. Le sqrt (valeur) est ce qui s'assure que la densité de vos points aléatoires est uniforme. Comme d'autres questions ont mentionné, vous voulez une distribution triangulaire pour cela; prendre le sqrt() transforme la distribution uniforme sur [0,1) en triangulaire.

Pour un cylindre, vous ne voulez pas le sqrt(); la partie incurvée est:

cylinder_point= point3d(R*cos(angle), R*sin(angle), H*value) 
0

D'autres réponses ont déjà couvert le boîtier du cylindre. Pour le cône, les choses sont un peu plus difficiles. Pour maintenir une densité constante de points, vous devez compenser le changement de rayon.

Pour ce faire, vous pouvez commencer en choisissant une distance entre les points. En vous déplaçant le long de l'axe du cône, vous calculez la circonférence à cette hauteur, puis divisez la circonférence par la distance linéaire entre les points pour obtenir le nombre de points. Vous divisez ensuite 2pi radians (ou 360 degrés, ou peu importe) par le nombre de points pour obtenir la distance angulaire pour ce rayon.

Selon la précision dont vous avez besoin, vous pouvez suivre le reste d'un cercle lorsque vous calculez le cercle suivant. Par exemple, si vous avez deux cercles d'affilée qui ont besoin de xxx.4 points, vous pouvez arrondir chaque point si vous les regardez séparément - mais en les regardant ensemble, vous avez xxx.8 points, alors vous devriez arrondir l'un vers le bas et l'autre vers le haut pour maintenir la densité globale aussi proche que possible de la valeur correcte.

Notez que, bien que ce ne soit pas aussi évident, ce dernier peut également s'appliquer au cylindre - vous aurez généralement quelques arrondis dans la distribution de chaque cercle de points.