Generazione di geometria procedurale


10

Di recente ho esaminato SceneKit per OS X e ho notato che esistono diversi metodi di fabbrica per creare forme geometriche come:

Scatola, capsula, cono, cilindro, piano, piramide, sfera, toro e tubo.

Sono interessato ad aggiungere forme così primitive al mio renderer, ma sto lottando per trovare una fonte ragionevole da cui posso ottenere una comprensione della generazione procedurale. Esistono diverse risorse che descrivono in dettaglio la teoria, ma mancano del codice sorgente appropriato per eseguirne il backup.

SceneKit fornisce metodi di fabbrica che consentono di impostare dinamicamente gli attributi di tali forme. Nel caso del riquadro, è possibile fornire valori interi per il numero di segmenti di larghezza, altezza e profondità in cui ciascuna faccia deve essere divisa.

Capisco la teoria ma non ho le conoscenze per iniziare a suddividere le facce della geometria per ottenere l'effetto desiderato.

I vertici per ciascuna forma sono molto probabilmente abbastanza facili da generare in semplici anelli. Ciò che mi sorprende è sapere come creare le facce, o meglio le coordinate di trama appropriate per ogni faccia. Le normali possono essere calcolate per faccia, quindi sono abbastanza fiducioso di poter ottenere quello che voglio, è solo sapere da dove cominciare.

Qualcuno può fornire dettagli sulla geometria procedurale? Quello di cui ho davvero bisogno è un codice sorgente per ottenere alcune informazioni. Ho cercato in alto e in basso tutorial, ma finora ho trovato solo pochi siti o blog ragionevoli. Tutti i buoni libri, tutorial, blog o articoli di ricerca sarebbero apprezzati.

Modifica in base ai commenti

Avrei dovuto chiarire che so come creare vertici per forme di base, la maggior parte di queste può essere probabilmente ottenuta con semplici loop. Quello che non capisco è come creare facce dalla matrice generata di vertici. Come faccio a creare una striscia triangolare, o triangoli, da una matrice apparentemente non ordinata di vertici?

Presumo che una volta superato questo punto, posso creare le normali da ogni faccia. Anche se non ho ancora approfondito questo aspetto, ho visto molti riferimenti a questo e sono sicuro che sarà abbastanza facile da implementare.

Idealmente, vorrei essere in grado di generare la geometria da un determinato set di proprietà come il modo fornito da SceneKit. Dato che SceneKit lo ha fatto, e puoi fare cose simili in Blender, Maya, ecc., Presumo che non sto cercando di implementare l'impossibile.

L'aspetto finale sarebbe l'applicazione di trame. Ancora una volta, questo non è qualcosa che ho implementato ma ho letto e sono consapevole dei requisiti.

Il problema principale qui è che so cosa voglio raggiungere ma sto lottando per decifrare come implementare per i primitivi di cui sopra. Speravo di riuscire a trovare una parvenza di conoscenza tramite il codice sorgente, ma finora non ho trovato nulla di adatto.


Dici che il tuo problema è la suddivisione della geometria, ma poi dici che creare i vertici dovrebbe essere facile, e poi dici che il tuo problema è come creare facce, e poi dici che il tuo problema è la mappatura delle trame. Qual è il tuo problema? Puoi generare le posizioni dei vertici? Riesci a generare i bordi e le facce? Inoltre, le coordinate della trama dipendono dalla trama e da ciò che si desidera ottenere con essa, quindi la domanda sulle coordinate della trama non è buona. Infine, la generazione di primitive riguarda semplicemente la geometria e le persone raramente la chiamano "geometria procedurale", sebbene sia così.
jrsala,

Capisco come creare la geometria per forme semplici come un cubo o un piano, è la creazione delle facce che non capisco. Come faccio a creare le facce da un gruppo di vertici? Tracciare i punti per forme più complesse è parte del problema anche se ho una comprensione di base. Incollarli tutti insieme in una striscia triangolare o triangoli è ciò che sto lottando per avvolgere la testa.
CaptainRedmuff,

OK, grazie per i dettagli. Potresti voler modificare la tua domanda per chiarire. Tempo di risposta!
jrsala,

Risposte:


11

Il modo di generare i bordi e le facce di una forma primitiva come una scatola, un cono e tutti quelli che hai citato è di generarli nello stesso momento in cui crei i vertici. In effetti, dovresti creare i vertici in modo logico che semplifichi il calcolo dei bordi e delle facce di conseguenza.

Esistono algoritmi che prendono come input una serie di punti nello spazio e calcolano una cosiddetta " triangolazione di set di punti " su di essa, ma il problema della triangolazione di set di punti è NP-completo , quindi è più veloce creare bordi e facce man mano che vai a calcolare i vertici e lascia che un algoritmo faccia il lavoro. Solo per farti sapere che esiste questa soluzione.

A parte questa soluzione inefficiente, credo che si possano trattare i primitivi solo per caso, come negli esempi che seguono.

Una mesh è costituita da vertici e facce . I bordi sono contenuti nella descrizione delle facce a meno che la mesh non contenga linee che non formano facce. I vertici sono tuple di 3 coordinate in virgola mobile. I bordi sono semplicemente coppie di riferimenti ai vertici, ma sicuramente non ne avrai più bisogno. Supponiamo ad esempio che i vertici si trovino in una matrice indicizzata. Bene, i tuoi bordi potrebbero quindi essere coppie di indici di quell'array. Le facce sono triplette di riferimenti a vertici o triplette di indici nel caso di matrice indicizzata .

Dovresti essere in grado di contare i vertici, i bordi e le facce che compongono ciascuna di queste forme primitive perché essere in grado di contarle significa comprendere le proprietà dell'oggetto che ti aiuta a escogitare il metodo con cui le costruirai, usando i cicli e altri strumenti come vedremo.

Cono

Per un cono con n + 2 vertici, bordi 3n e facce 2n :

  1. Crea due vertici separati.
  2. Fai un cerchio attorno a uno dei vertici (il vertice di base), che si trova all'interno di un piano perpendicolare al segmento tra i primi due vertici. Spero che tu possa fare un cerchio usando la trigonometria, giusto? Sono già tutti i vertici del cono. Questo è anche un terzo di tutti i bordi (ci sono n bordi nel cerchio e 3n in totale).
  3. Crea n bordi dal vertice di base agli n vertici nel cerchio. Puoi creare metà delle facce (ovvero n facce) mentre lo fai.
  4. Crea n bordi dal vertice della punta agli n vertici nel cerchio. Puoi fare l'altra metà delle facce (ovvero n facce) mentre lo fai.

1) Due vertici 2) e un cerchio
3) e facce
4) e facce
Risultato finale:risultato

Puoi anche creare i bordi e le facce mentre esegui il ciclo che crea il cerchio. Stessa complessità, stessa cosa. Crea un vertice sul cerchio, memorizzalo nella tua matrice di vertici, aggiungi il bordo corrispondente (coppia di indici) alla matrice di coppie di indici se ti va, e infine aggiungi la faccia corrispondente alla tua matrice di terzine di indici . Passa al vertice successivo.

Il cilindro e il tubo: non fare lo stesso lavoro due volte e quadrupli

Ancora una volta, per il tubo inizia con un vertice e un cerchio che sarà il centro del disco superiore o inferiore del cilindro:

  1. Crea un vertice.
  2. Fai un cerchio attorno al vertice. Aggiungi i bordi (se vuoi i bordi) tra i vertici successivi del cerchio e tra il vertice centrale e ciascun vertice del cerchio. Aggiungi facce tra ogni tripletta di vertici fatta del vertice centrale e due vertici successivi sul cerchio.
  3. Duplica tutto ciò, traduci la copia nella direzione perpendicolare alla base appena creata, per la lunghezza del cilindro desiderato.
  4. Collega la parte superiore e inferiore.

Per collegare la parte superiore e inferiore, è necessario creare quadratini tra coppie di coppie di vertici rivolti l'uno verso l'altro. Quindi pensa al futuro e perché non renderti una funzione che fa due facce triangolari su quattro vertici?

Fatto. Si noti che questa volta usiamo il fatto che la stessa struttura (cerchio + centro) appare due volte in un cilindro per prendere una scorciatoia. Non dobbiamo realizzare tutti i vertici, i bordi e le facce a mano, contrariamente al cono dove era necessario.

Seguendo questo principio di pigrizia, è anche possibile creare solo un quarto del cerchio e duplicarlo, e ancora, per creare un cerchio completo con trasformazioni molto semplici (valido con qualsiasi cerchio, quindi anche con il cono), ma è davvero eccessivo per un forma non così complessa.

Devi sempre usare le proprietà geometriche degli oggetti che fai per semplificarne la realizzazione . Vale a dire, le loro simmetrie e invarianti .

Per un cilindro, semplicemente non creare il vertice di base, basta creare il cerchio, duplicare, tradurre la copia, creare i quad, fatto.

La sfera e la capsula: aggiungendo complessità, ancora non lo stesso lavoro due volte

Per creare una capsula, vogliamo creare una sfera UV, dividerla in due metà, tradurre la prima metà e quindi collegare i due con i lati delle capsule.

Ancora una volta è possibile creare solo un ottavo (!!) della sfera, quindi duplicarlo e invertirlo, quindi duplicare e invertire il risultato tranne che lungo un altro asse, ecc., Per ottenere una sfera completa, in 4 passaggi (creare l'ottavo , duplica e inverti tre volte). Forse eccessivo, ma meno che nel caso del cerchio.

Una semplice sfera UV:
sfera

In effetti ne facciamo solo una metà (per esempio), dupliciamo quella metà, capovolgiamo la copia e la traduciamo per la lunghezza della capsula:
metà

Colleghiamo la metà superiore e inferiore:
capsula

Il vero (in qualche modo) duro lavoro viene dalla trigonometria che va a formare una sfera. L'insieme di tutti i vertici appartenenti a una sfera UV può essere descritto come l'insieme di tutti i punti del modulo:

punti

dove R è il raggio della sfera e, per un certo numero intero pari positivo N , abbiamo la costante

θ = × π / N ,

k e n sono numeri interi con k che varia da 0 a 2N-1 e n che varia da -N / 2 a + N / 2 .

Per creare una semisfera o un ottavo di sfera, devi limitare l'insieme di valori presi da k e n .

Se k fossero numeri reali e non solo numeri interi, otterresti un'intera sfera, non solo i vertici sulla sua superficie. Quindi quello che abbiamo fatto qui è rasterizzare l'equazione di superficie della primitiva .

Il temibile toro : è facile dopo tutto quello che abbiamo visto!

Ancora una volta, più trigonometria, più vertici, più quad, più simmetrie, più invarianti ... più geometria! Scopri l'equazione per la superficie di un toro, "rasterizzalo correttamente", semplifica il problema usando le (ovvie) simmetrie del toro e, infine, esegui il ciclo dell'insieme di vertici che hai appena definito e crea bordi e facce come partire!

Vedere? Completamente semplice.


Wow. Grazie per la risposta così dettagliata e per tanti esempi. Non avevo considerato l'idea di generare semplicemente metà di una sfera e rispecchiare gli elementi simmetrici. Mille grazie per aver dedicato del tempo a scrivere questo in un modo che posso facilmente capire e spero di mettere in pratica con facilità.
CaptainRedmuff,

Prego! Mi dispiace però non esistesse un codice.
jrsala,

Lo schema dei metodi era più di quello di cui avevo davvero bisogno. Posso iniziare a elaborare un piano d'azione da lì almeno:] Non suppongo che tu abbia informazioni su Scatole / Cubi con bordi smussati? docs.autodesk.com/3DSMAX/15/ENU/3ds-Max-Help/images/…
CaptainRedmuff

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.