Comment générer par programmation une sphère?

25

Quelqu'un pourrait-il expliquer comment il serait possible de créer une sphère sommets, indices et coordonnées de texture? Il y a un manque surprenant de documentation sur la façon de le faire et c'est quelque chose que je suis intéressé à apprendre.

J'ai essayé l'évidence, googler, regarder sur gamedev.net, etc. Cependant, rien ne couvre les générations de points sphériques, les indexant et les textures.

judeclarke
la source
6
Je ne vais pas voter contre ou voter pour clôturer cela, mais me dites-vous vraiment que pas un seul résultat de google.com/search?q=how+to+generate+a+sphere+vertices n'était utile? Si tel est le cas, vous devrez expliquer plus en détail votre problème.
Recherchez l'icosphère. Beaucoup plus intelligent que la "sphère polaire" muette qui produit des visages inutiles.
Notabene
3
À noter, à des fins simples, une "sphère" parfaitement fine est un quad avec une texture circulaire face à la caméra.
aaaaaaaaaaaa
Voici comment je l'ai implémenté pour le skydome dans mon jeu.
danijar

Réponses:

36

Il existe deux approches générales:

entrez la description de l'image ici

La plus à gauche est appelée la sphère uv et la plus à droite une icosphère.

GLUT a tendance à utiliser l'approche uv: regardez la fonction glutSolidSphere()dans le code source freeglut .

Voici un excellent article sur la production d'une icosphère: http://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html

La sphère uv ressemble à un globe. À de nombreuses fins, il est parfaitement fin, mais pour certains cas d'utilisation, par exemple si vous souhaitez déformer la sphère, il est désavantageux que la densité des sommets soit plus grande autour des pôles. Ici, l'icosphère est meilleure, ses sommets sont répartis uniformément.

Vous pouvez également trouver cela intéressant: http://kiwi.atmos.colostate.edu/BUGS/geodesic/text.html il décrit une approche pour organiser les visages en zones.

http://vterrain.org/Textures/spherical.html donne une excellente description de la façon dont vous pouvez choisir de les texturer.

Volonté
la source
2
Bien que l'idée générale soit bonne, la subdivision d'un polytope Schläfli {3,5} n'est pas la seule façon de le faire. En général, je préfère travailler avec la famille Schläfli {4, *} ({4,3} dans le cas d'une sphère) à des fins de cartographie UV.
Martin Sojka
Les sphères icosaédriques finement tessellées sont un peu plus chères à générer en raison de la nécessité de subdiviser récursivement les faces.
bobobobo
9

Il y a 2 façons de procéder:

  1. Parcourez thêta et phi en coordonnées sphériques, générez des visages et des tris

  2. Créez un icosaèdre et subdivisez récursivement les faces jusqu'à ce que la tessellation souhaitée soit atteinte.

Sphère utilisant des coordonnées sphériques à pied

Pour la première façon, vous utilisez simplement un double imbriqué pour parcourir thêta et phi. En parcourant thêta et phi, vous faites tourner des triangles pour créer votre sphère.

entrez la description de l'image ici

Le code qui le fait ressemblera à ceci:

for( int t = 0 ; t < stacks ; t++ ) // stacks are ELEVATION so they count theta
{
  real theta1 = ( (real)(t)/stacks )*PI ;
  real theta2 = ( (real)(t+1)/stacks )*PI ;

  for( int p = 0 ; p < slices ; p++ ) // slices are ORANGE SLICES so the count azimuth
  {
    real phi1 = ( (real)(p)/slices )*2*PI ; // azimuth goes around 0 .. 2*PI
    real phi2 = ( (real)(p+1)/slices )*2*PI ;

    //phi2   phi1
    // |      |
    // 2------1 -- theta1
    // |\ _   |
    // |    \ |
    // 3------4 -- theta2
    //

    //vertex1 = vertex on a sphere of radius r at spherical coords theta1, phi1
    //vertex2 = vertex on a sphere of radius r at spherical coords theta1, phi2
    //vertex3 = vertex on a sphere of radius r at spherical coords theta2, phi2
    //vertex4 = vertex on a sphere of radius r at spherical coords theta2, phi1

    // facing out
    if( t == 0 ) // top cap
      mesh->addTri( vertex1, vertex3, vertex4 ) ; //t1p1, t2p2, t2p1
    else if( t + 1 == stacks ) //end cap
      mesh->addTri( vertex3, vertex1, vertex2 ) ; //t2p2, t1p1, t1p2
    else
    {
      // body, facing OUT:
      mesh->addTri( vertex1, vertex2, vertex4 ) ;
      mesh->addTri( vertex2, vertex3, vertex4 ) ;
    }
  }
}

Donc, notez ci-dessus, il est important d'enrouler le capuchon supérieur et le capuchon inférieur en utilisant uniquement des tris, pas des quads.

Sphère icosaédrique

POUR utiliser un icosaèdre, il vous suffit de générer les points de l'icosaèdre, puis d'enrouler des triangles. Les sommets d'un icosaèdre assis à l'origine sont:

(0, ±1, ±φ)
1, ±φ, 0)
(±φ, 0, ±1)
where φ = (1 + 5) / 2 

Il suffit ensuite de regarder un diagramme d'un icosaèdre et des faces de vent de ces verts. J'ai déjà du code qui le fait ici .

bobobobo
la source
des idées comment obtenir le demi-corps, comme de thêta = pi / 4 à thêta = 3pi * 4? Comme cette image: i.stack.imgur.com/Jjx2c.jpg Je passe des jours à résoudre ce problème.
Tina J
3

Si les points ne doivent pas nécessairement être localement uniformes, mais doivent être globalement uniformes et ne doivent suivre aucun modèle défini, vous pouvez utiliser une variante de l'algorithme de lancement de fléchettes pour distribuer n points sur une sphère de rayon r , en moyenne dist points à part. Ces valeurs sont alors approximativement:

  1. Si vous souhaitez avoir une quantité spécifique de sommets:
    • n = (quantité désirée de sommets)
    • dist = 2 × r × √ ( π / n )
  2. Si vous souhaitez avoir une distance moyenne spécifique entre les sommets:
    • n = 4 × π × ( r / dist ) 2
    • dist = (distance moyenne souhaitée)

Dans le cas le plus simple, vous pouvez ensuite sélectionner uniformément des points au hasard en sélectionnant deux variables uniformément réparties u et v de (0, 1) et en calculant les coordonnées polaires à partir d'elles selon les formules θ = 2 × π × u et ϕ = arc cos (2 × v - 1); puis en supprimant tous les points trop proches des points déjà sélectionnés. Pour un algorithme légèrement plus complexe et nettement plus performant, voir " Dart Throwing on Surfaces " de Cline, Jeschke, White, Razdan et Wonka.

Après avoir choisi vos quatre premiers points (en supposant qu'aucun d'entre eux n'est dégénéré , c'est-à-dire qu'ils ne se trouvent pas sur le même grand cercle, mais c'est très peu probable), vous pouvez créer quatre faces entre eux, et chaque fois que vous ajoutez un nouveau point, vous pouvez diviser la face à laquelle il appartient en conséquence en trois sous-faces.

À des fins de texturation, vous pouvez ensuite mapper les points sur une carte de cube.

Martin Sojka
la source