Rappresentazione sferica della mappa


19

Il mio ultimo gioco si svolgerà su un piccolo planetoide. Sto cercando una buona struttura di dati per rappresentare le celle sulla superficie di una sfera. Triangoli, quadrati, pentagoni, esagoni? Quale minimizza di più lo stiramento e crea la migliore piastrellatura?

La mappatura sferica è la più semplice ma l'allungamento ai poli è inaccettabile. Anche il cubemapping è abbastanza semplice ma ci sarebbe comunque un notevole allungamento vicino agli angoli del cubo. Suddividere un icosaedro sembra il migliore in termini di allungamento, ma esiste il problema di indicizzare molte matrici triangolari e trovare celle vicine ai confini sarebbe difficile.

Immagino di poter usare un singolo array lineare di punti che rappresentano N-gon, ciascuno con un array di N indici vicini, ma sembra un enorme spreco di spazio.

Il gioco ha elementi RTS, quindi memorizzerò cose come mappe di influenza ed eseguirò l'indirizzamento e la convoluzione A *, quindi la rappresentazione deve essere efficiente.


Quanto è importante la topologia esatta della mappa, invece di lasciare che gli attori vadano in una direzione e alla fine finiscano da dove hanno iniziato? La rappresentazione più semplice ed efficiente sarebbe un toro / ciambella.
congusbongus,

1
Sì, ho menzionato la mappatura sferica e i problemi che ha con i poli. Voglio memorizzare i valori intorno alla superficie, quindi ho bisogno di una mappatura dal punto della superficie 3D all'indice dell'array con il minor allungamento possibile.
DaleyPaley,

Potresti provare a suddividere un tetraedro per creare una sfera. È costituito da triangoli equamente dimensionati e distribuiti.
Thalador,

1
@thalador Grazie per il suggerimento. Non sono sicuro ma penso che gli icosaedri siano migliori dei tetraedri se seguo il percorso triangolare. Ma comunque, la tassellatura non è il problema. È l'indicizzazione dell'array efficiente che mi dà fastidio.
DaleyPaley

Risposte:


12

Va bene, per chiunque sia interessato a questo argomento, descriverò ora in dettaglio la soluzione che ho scelto. Grazie a tutti coloro che hanno risposto e mi hanno dato idee.

Innanzitutto, per la "migliore" tassellatura, sceglierò l' icosaedro troncato come punto di partenza. Suddividendola si ottiene una piacevole tessellazione di esagoni con 12 pentagoni che forniscono la curvatura. Inoltre, continuare la suddivisione sul suo doppio mi darà un'ottima mesh triangolare per il rendering con belle proprietà. Per quanto riguarda le 12 celle pentagonali: posso ignorarle, renderle speciali (come gli unici posti in cui è possibile costruire basi), oppure posso nasconderle in uno scenario.

Le celle esagonali e pentagonali saranno archiviate in una struttura dati a metà bordo per un facile accesso ai vicini e un rapido spostamento. L'unica parte difficile è trovare in quale cella si trova un dato punto del mondo, ma ciò può essere fatto partendo da una cella casuale e camminando verso il punto attraverso i vicini.

Spero che qualcuno trovi utile questa informazione. Ho imparato molto e non vedo l'ora di ottenere alcuni risultati.

Modificare:

Ecco un'immagine che mostra il risultato della mia suddivisione dell'icosaedro e la commutazione a doppia mesh utilizzando la struttura dei dati a metà bordo.

Potrei fare alcune iterazioni di rilassamento per rendere le aree cellulari ancora più uniformi.

suddivisione degli icosaedri


7

C'è un modo per farlo piuttosto elegantemente basato sulla suddivisione di un icosaedro, come hai suggerito nella tua domanda. Un icosaedro è composto da 20 triangoli equilateri e questi triangoli possono essere raggruppati in 5 set, in cui i 4 triangoli in un set formano una forma a parallelogramma:

inserisci qui la descrizione dell'immagine

(I gruppi di quattro triangoli con uno scarabocchio tra loro sono i parallelogrammi di cui sto parlando. Le frecce indicano quali bordi sarebbero incollati insieme per piegare questo in un icosaedro.)

Se questi triangoli sono suddivisi in triangoli più piccoli, l'intero parallelogramma può essere indicizzato come una matrice rettangolare n per 4n (n = 4 nell'esempio):

inserisci qui la descrizione dell'immagine

I numeri in ciascuna cella sono i numeri di colonna dell'array rettangolare. Le regole per trovare i vicini nell'array sono abbastanza semplici: i vicini orizzontali sono solo più o meno 1 colonna, mentre il vicino verticale è meno una riga e più una colonna, oppure più una riga e meno una colonna, a seconda che il il numero di colonna è pari o dispari, rispettivamente.

Tuttavia, devi ancora scrivere un codice per casi speciali per trovare vicini che attraversano il confine da un parallelogramma al successivo. È un po 'complicato poiché in alcuni punti, la parte superiore o inferiore di un parallelogramma sarà collegata al lato di un altro, oppure la parte superiore e quella inferiore saranno collegate con un offset orizzontale tra loro, ecc. Probabilmente una struttura a metà bordo o simile per i parallelogrammi sarebbe utile qui. Tuttavia, almeno le relazioni sono simmetriche tra tutti e 5 i parallelogrammi: seguono tutti lo stesso schema in cui il lato è collegato a quale altro lato dei loro vicini.


Questa è davvero una rappresentazione molto bella. La mia principale preoccupazione con i metodi triangolari era con il mantenimento di matrici triangolari e tutte le cuciture. C'è ancora un po 'di cuciture qui, ma le matrici sono rettangolari. Grazie, molto buono a sapersi
DaleyPaley,

3

Hmmm - i commenti sull'allungamento indicano che ti stai muovendo tra mappatura sferica e planare, questo è ciò che porta alle distorsioni ai poli

Se vuoi che le piastrelle siano piatte e uniformi, hai ragione nel dire che un icosaedro, in particolare un icosaedro troncato, è abbastanza comune

Puoi trovare tutte le diverse mappature qui - poliedri sferici su wikipedia

Per quanto riguarda il mantenimento delle relazioni tra le facce, che è un problema di topologia - si potrebbe trovare uno spigolo alato o bordo quad disponibile (e si ottiene la meravigliosa opportunità di incontrare una nuova forma di algebra) alato Bordo


Ah, un icosaedro troncato. Sì, è esattamente quello di cui ho bisogno. Grazie. Inoltre, anche se non ho mai usato il bordo alato, ho usato molto i mezzi bordi per manipolare le maglie, quindi sono molto esperto in quella zona. Saluti, sono vicino a una soluzione.
DaleyPaley

2

Immagino che arriverò un po 'in ritardo alla festa, ma ecco una possibile soluzione che può essere utilizzata per mantenere un mondo sferico di dimensioni arbitrarie e aspetto uniforme.

La cosa chiave da capire qui è che il mondo non è piatto, e quindi una piastrellatura uniforme al 100% sarebbe impossibile (questo segue dal cosiddetto Teorema della Sfera Pelosa ). Alcune irregolarità devono essere ammesse e il meglio che possiamo sperare è di diffondere tali irregolarità uniformemente sulla superficie, rendendole più piccole possibili.

In realtà è abbastanza facile da fare in modo non deterministico. Innanzitutto, scegli N punti casuali uniformemente intorno alla superficie. Assicurati che quei punti siano effettivamente uniformi (vedi Selezione del punto Sfera , formule 9-11). Nel secondo passo rendiamo quei punti meno casuali e più uniformi: supponiamo che tutti quei punti abbiano una carica elettrica negativa in modo che si respingano a vicenda. Simula il movimento dei punti per diversi passaggi, fino a quando non convergono in uno stato di equilibrio. Questa configurazione finale dei punti ti darà una maglia che è distribuita quasi uniformemente intorno alla superficie della sfera.


1
Non avevo mai sentito parlare della teoria della palla pelosa, è abbastanza interessante. Devo impedirmi di fare battute puerili. Ho già distribuito punti su sfere prima in quel modo, ma il problema è che la poligonizzazione è molto più lenta della suddivisione di un politopo. Inoltre, le forme e la valenza delle cellule saranno troppo non uniformi per i miei gusti. Ma grazie comunque.
DaleyPaley,
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.