PDA

View Full Version : [OpenGL] "Arrotondamento" di un Icosaedro Regolare


AnonimoVeneziano
01-04-2005, 14:44
Ciao boys.

Mi stavo leggendo il "Libro Rosso" dell' OpenGL e alla fine del 2° capitolo mi sono trovato davanti alla funzione per la segmentazione di un Icosaedro (funzione per dividere in + facce un icosaedro per ottenerene una forma + "sferica" ) :

Mi sfugge abbastanza però abbastanza il funzionamento di tale funzione .

La funzione del libro è questa :



void drawtriangle(float *v1, float *v2, float *v3)
{
glBegin(GL_TRIANGLES);
glNormal3fv(v1); vlVertex3fv(v1);
glNormal3fv(v2); vlVertex3fv(v2);
glNormal3fv(v3); vlVertex3fv(v3);
glEnd();
}

void subdivide(float *v1, float *v2, float *v3)
{
GLfloat v12[3], v23[3], v31[3];
GLint i;

for (i = 0; i < 3; i++) {
v12[i] = v1[i]+v2[i];
v23[i] = v2[i]+v3[i];
v31[i] = v3[i]+v1[i];
}
normalize(v12);
normalize(v23);
normalize(v31);
drawtriangle(v1, v12, v31);
drawtriangle(v2, v23, v12);
drawtriangle(v3, v31, v23);
drawtriangle(v12, v23, v31);
}

for (i = 0; i < 20; i++) {
subdivide(&vdata[tindices[i][0]][0],
&vdata[tindices[i][1]][0],
&vdata[tindices[i][2]][0]);
}


In pratica quello che fa è prendere in input i vertici di uno dei triangoli che compongono l'icosaedro e segmentarlo in quattro parti, in pratica alla fine del processo il triangolo diventa così :

3
/\
/ \
v31/_____\ v23
/\ /\
/ \ / \
/____\/_____\
1 v12 2

(sperando la formattazione del testo non me l'abbia disfato EDIT: si , ovviamente mi si era disfato) .

Sul libro c'è scritto che il lavoro che fa normalizzando i vertici "v12", "v23" e "v31" in pratica si riportano in superficie i vertici che compongono la superficie di una ipotetica sfera circoscritta all' icosaedro , ecco la frase che intendo :

"A twenty-sided approximation to a sphere (l'icosaedro) doesn't look good unless the image of the sphere on the screen is quite small, but there's an easy way to increase the accuracy of the approximation. Imagine the icosahedron inscribed in a sphere, and subdivide the triangles as shown in Figure 2-17. The newly introduced vertices lie slightly inside the sphere, so push them to the surface by normalizing them (dividing them by a factor to make them have length 1). This subdivision process can be repeated for arbitrary accuracy. The three objects shown in Figure 2-17 use 20, 80, and 320 approximating triangles, respectively."

Quello che vorrei mi venisse chiarito è :

1) perchè somma i vari componenti dei vertici con
for (i = 0; i < 3; i++) {
v12[i] = v1[i]+v2[i];
v23[i] = v2[i]+v3[i];
v31[i] = v3[i]+v1[i];
}
??

Io mi aspettavo che poi ne facesse la media, invece si limita a sommare

2) Perchè normalizzare i nuovi vertici ottenuti?? Cosa vuol dire in realtà questa frase? Perchè normalizzare tali vertici (ossia dividerli per un fattore che rende il vettore di lunghezza 1) dovrebbe "portare fuori il vertice" per far assomigliare di + l'icosaedro a una sfera?

3) Normalizzare crea valori che stanno sempre sotto l' 1. Se per caso le coordinate del mio icosaedro andassero oltre l'1 e poi i vertici venissero normalizzati sicuramente succederebbe un pastrocchio (ho provato a fare un icosaedro con coordinate nell' ordine di 1, 23 e con distanza dal centro di 2 col risultato di ottenere una specie di stella marina tridimensionale al posto della sfera che invece con valori di 0.9 e 0.55 ottenevo .

Grazie per le eventuali risposte

Ciao

Passy
01-04-2005, 16:29
Hai una signature veramente fica hahahah sei mitico :D :D :D

AnonimoVeneziano
01-04-2005, 16:38
LOL , grazie :D

Ovviamente si scherza :p

Comunque colgo l'occasione del post per farvi vedere i 2 risultati che ottengo, uno coi valori originali di dimensioni dell' icosaedro, l'altro con le nuove dimensioni > di 1 con le quali ottengo un risultato scorretto (le dimensioni sono comunque corrette per un icosaedro , infatti tenendo solo quelle e non segmentando viene un icosaedro bene o male corretto considerando che ho approssimato un po' i valori del rapporto aureo ) :

#define LG .850650808352039932
#define LP .525731112119133606

GLfloat vertici[12][3] = { {-LP, 0.0, LG}, {LP, 0.0, LG}, {0.0, LG, LP},
{0.0, -LG, LP}, {-LG, -LP, 0.0}, {-LG, LP, 0.0},
{LG, -LP, 0.0}, {LG, LP, 0.0}, {-LP, 0.0, -LG},
{LP, 0.0, -LG}, {0.0, LG, -LP}, {0.0, -LG, -LP}
};

int indici[20][3] = { {0, 1, 2}, {5, 0, 2}, { 10, 5, 2}, { 7, 10, 2},
{ 1, 7, 2}, { 1, 0, 3}, {6, 1, 3}, {11, 6, 3 },
{4, 11, 3}, { 0, 4, 3 }, {5, 4, 0}, { 4, 5, 8},
{6, 7, 1}, {7, 6, 9}, {9, 8, 10}, {8, 9, 11},
{8, 5, 10}, {7, 9, 10}, {6, 11, 9}, {11, 4, 8}
};


http://www.webalice.it/hayarms/texico2.jpg


#define LG 2
#define LP 1.23

int finestra;
GLfloat vertici[12][3] = { {-LP, 0.0, LG}, {LP, 0.0, LG}, {0.0, LG, LP},
{0.0, -LG, LP}, {-LG, -LP, 0.0}, {-LG, LP, 0.0},
{LG, -LP, 0.0}, {LG, LP, 0.0}, {-LP, 0.0, -LG},
{LP, 0.0, -LG}, {0.0, LG, -LP}, {0.0, -LG, -LP}
};

int indici[20][3] = { {0, 1, 2}, {5, 0, 2}, { 10, 5, 2}, { 7, 10, 2},
{ 1, 7, 2}, { 1, 0, 3}, {6, 1, 3}, {11, 6, 3 },
{4, 11, 3}, { 0, 4, 3 }, {5, 4, 0}, { 4, 5, 8},
{6, 7, 1}, {7, 6, 9}, {9, 8, 10}, {8, 9, 11},
{8, 5, 10}, {7, 9, 10}, {6, 11, 9}, {11, 4, 8}
};



http://www.webalice.it/hayarms/texico.jpg


Ciao!

Passy
01-04-2005, 20:53
C@zz@ bello... anche a me piacerebbe provare imparare a usare OpenGL

Ma mi manca il tempo (come a tutti) quindi si cerco di imarare a fare quello che mi serve :cry:

Adesso sto scrivento una applicazione per gestire iptables (facilmente)

Ciao