Come si genera a livello di codice una sfera?


25

Qualcuno potrebbe spiegare come sarebbe possibile creare una sfera vertici, indici e coordinate di trama? C'è una sorprendente mancanza di documentazione su come farlo ed è qualcosa che mi interessa imparare.

Ho provato l'ovvio, cercando su Google, guardando su gamedev.net, ecc. Tuttavia, nulla copre le generazioni di punti sferici, indicizzandoli e texturizzando.


6
Non ho intenzione di sottovalutare o votare per chiudere questo, ma mi stai davvero dicendo che non è stato utile un solo risultato da google.com/search?q=how+to+generate+a+sphere+vertices ? In tal caso, dovrai spiegare in modo più dettagliato il problema.


Cerca icosfera. Molto più intelligente della muta "sfera polare" che produce facce inutili.
Notabene,

3
Vale la pena notare che per alcuni semplici scopi una "sfera" perfettamente raffinata è un quad con una trama circolare rivolta verso la telecamera.
aaaaaaaaaaaa,

Ecco come l'ho implementato per lo skydome nel mio gioco.
danijar,

Risposte:


36

Esistono due approcci generali:

inserisci qui la descrizione dell'immagine

L'estrema sinistra è definita la sfera uv e l'estrema destra un'icosfera.

GLUT tende ad usare l'approccio uv: guarda la funzione glutSolidSphere()nel codice sorgente freeglut .

Ecco un eccellente articolo sulla produzione di un'icosfera: http://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html

La sfera UV sembra un globo. Per molti scopi è perfettamente corretto, ma per alcuni casi d'uso, ad esempio se si desidera deformare la sfera, è svantaggioso che la densità dei vertici sia maggiore attorno ai poli. Qui l'icosfera è migliore, i suoi vertici sono distribuiti uniformemente.

Potresti anche trovare questo interessante: http://kiwi.atmos.colostate.edu/BUGS/geodesic/text.html descrive un approccio all'organizzazione delle facce in zone.

http://vterrain.org/Textures/spherical.html fornisce un'eccellente descrizione di come potresti scegliere di strutturarli.


2
Mentre l'idea generale è buona, suddividere un polytope di Schläfli {3,5} non è l'unico modo per farlo. In generale, preferisco lavorare con la famiglia Schläfli {4, *} ({4,3} nel caso di una sfera) per scopi di mappatura UV.
Martin Sojka,

Le sfere icosaedriche finemente tassellate sono un po 'più costose da generare a causa della necessità di suddividere ricorsivamente le facce.
Bobobobo,

9

Ci sono 2 modi per farlo:

  1. Cammina theta e phi in coordinate sferiche, genera facce e tris

  2. Crea un icosaedro e suddivide ricorsivamente le facce fino a raggiungere la tassellatura desiderata.

Sfera che utilizza coordinate sferiche cammina

Per prima cosa, basta usare un doppio nidificato per camminare theta e phi. Mentre cammini theta e phi, giri i triangoli per creare la tua sfera.

inserisci qui la descrizione dell'immagine

Il codice che lo farà sarà simile a questo:

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

Quindi, nota sopra, è importante avvolgere il tappo superiore e quello inferiore usando solo tris, non quad.

Sfera icosaedrica

Per usare un icosaedro, devi solo generare i punti dell'icosaedro e poi avvolgerne dei triangoli. I vertici di un icosaedro seduto all'origine sono:

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

Devi solo guardare il diagramma di un icosaedro e le facce del vento da quei verbi. Ho già il codice che lo fa qui .


qualche idea su come ottenere la metà del corpo, come da theta = pi / 4 a theta = 3pi * 4? Come questa immagine: i.stack.imgur.com/Jjx2c.jpg Ho passato giorni su questo non potevo risolverlo.
Tina J,

3

Se i punti non devono essere uniformi a livello locale, ma devono essere uniformi a livello globale e non devono seguire alcun modello impostato, è possibile utilizzare una variante dell'algoritmo di lancio di freccette per distribuire n punti su una sfera con raggio r , in media punti dist . Questi valori sono quindi approssimativamente:

  1. Se vuoi avere un numero specifico di vertici:
    • n = (quantità desiderata di vertici)
    • dist = 2 × r × √ ( π / n )
  2. Se vuoi avere una distanza media specifica tra i vertici:
    • n = 4 × π × ( r / dist ) 2
    • dist = (distanza media desiderata)

Nel caso più semplice, è possibile scegliere uniformemente punti a caso selezionando due variabili distribuite uniformemente u e v da (0, 1) e calcolando le coordinate polari dalle loro secondo le formule θ = 2 × π × u e φ = arco cos (2 × v - 1); quindi respingendo tutti i punti troppo vicini ai punti già selezionati. Per un algoritmo leggermente più complesso e significativamente più performante, vedi " Dart Throwing on Surfaces " di Cline, Jeschke, White, Razdan e Wonka.

Dopo aver selezionato i tuoi primi quattro punti (supponendo che nessuno di essi sia degenerato , cioè - non si trovano sullo stesso grande cerchio, ma è altamente improbabile), puoi creare quattro facce tra di loro e ogni volta che aggiungi un nuovo punto, puoi dividere la faccia a cui appartiene di conseguenza in tre facce secondarie.

A scopo di texturing è quindi possibile mappare i punti su una mappa cubica.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.