triangulation d'une sphere
Bonjour,
je cherche à modéliser une sphère en 3D par triangulation mais j'ai quelques problèmes d'algo. Je travaille en langage C avec la librairie d'OpenGL.
Code:
1 2 3 4 5 6 7 8
| struct StructSphere {
int _nbTriangles; // nombre de triangles à modéliser
GLfloat (*vertices)[3]; // tableau de sommets : l'indice du tableau est le numéro du sommet. Pour chaque sommet on stocke ses coordonnées x, y et z.
GLint (*triangles)[3]; // d'un tableau de triangles : l'indice du tableau est le numéro du triangle. Pour chaque triangle on stocke les indices de ses trois sommets
GLfloat (*normalsT)[3]; // d'un tableau de normales : dans la version simple on a autant de normales que de triangles. Ces normales sont les vecteurs normaux à chaque triangle.
}; |
L'algo trace des disques superposés en modifiant juste le rayon mais je pense que ce n'est pas le meilleur
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
| /*--- Sphere ---*/
void initSphere (Sphere * sphere , int nvertices)
{
int i;
int j;
int nbT;
nbT=0;
int nbD;
int nbV;
float r;
r = RAYON;
float rapport;
float aux;
aux = (nvertices/2) +1;
int i_sauv;
rapport = 1 / aux;
float h;
h = 0;
int disk;
disk = 0;
int nv;
nv = ( (nvertices+1) * nvertices) + 2;
// initialisation _nbTriangles wether nvertices is PAIR or IMPAIR
if ( (nvertices %2) == 0) sphere->_nbTriangles = (2*nvertices + 2) * nvertices;
else sphere->_nbTriangles = 2 * nvertices * nvertices;
// allocation dynamiqe
sphere->vertices = malloc(nv * sizeof (*sphere->vertices));
sphere->triangles = malloc(sphere->_nbTriangles * sizeof (*sphere->triangles));
sphere->normalsT = malloc(sphere->_nbTriangles * sizeof (*sphere->normalsT));
// calcul de l'angle
float teta = (2 * M_PI) /nvertices;
// premier disque du milieu
for (i=0; i<nvertices; i++) {
sphere->vertices[i][0] = r * cos(i*teta);
sphere->vertices[i][1] = r * sin(i*teta);
sphere->vertices[i][2] = 0;
}
// les autres disques
for( nbD=1; nbD<nvertices; nbD=nbD+2) {
h = h + rapport; // calcul pour diminuer la hauteur de chaque disque
r = r - (RAYON*rapport); // calcul pour diminuer le rayon de chaque disque
for( i=0; i<nvertices; i++) {
sphere->vertices[(nbD*nvertices)+i][0] = r * cos(i*teta);
sphere->vertices[(nbD*+nvertices)+i][1] = r * sin(i*teta);
sphere->vertices[(nbD*nvertices)+i][2] = h;
sphere->vertices[( (nbD+1)*nvertices) +i][0] = r * cos(i*teta);
sphere->vertices[( (nbD+1)*nvertices) +i][1] = r * sin(i*teta);
sphere->vertices[( (nbD+1)*nvertices) +i][2] = -h;
}
}
// dernier triangle du haut
sphere->vertices[nbD*nvertices][0] = 0;
sphere->vertices[nbD*nvertices][1] = 0;
sphere->vertices[nbD*nvertices][2] = RAYON;
// dernier triangle du bas
sphere->vertices[(nbD*nvertices)+1][0] = 0;
sphere->vertices[(nbD*nvertices)+1][1] = 0;
sphere->vertices[(nbD*nvertices)+1][2] = -RAYON;
// triangulation
for (nbD=0; nbD<nvertices; nbD++) {
// premier disque
if (nbD == 0) i_sauv = (nvertices-1) * nvertices;
else {
if (disk) { i_sauv = 0; disk = 0; }
else i_sauv = abs(i_sauv - 2*nvertices);
}
for(nbV=0; nbV<nvertices-1; nbV++) {
i = i_sauv + nbV;
// cas du disk au dessus du centre
j = i - 2*nvertices;
if ( j<0 && j>=-nvertices) {
j += nvertices;
disk = 1;
}
j = abs(j);
sphere->triangles[nbT][0] = i;
sphere->triangles[nbT][1] = j;
sphere->triangles[nbT][2] = j + 1;
sphere->triangles[nbT+1][0] = i;
sphere->triangles[nbT+1][1] = j + 1;
sphere->triangles[nbT+1][2] = i + 1;
nbT += 2;
}
i = i + 1;
j = i - 2*nvertices;
if ( disk) {
j += nvertices;
}
// les 2 derniers triangles d'un disque
sphere->triangles[nbT][0] = i;
sphere->triangles[nbT][1] = j;
sphere->triangles[nbT][2] = j - nvertices + 1;
sphere->triangles[nbT+1][0] = i;
sphere->triangles[nbT+1][1] = j - nvertices + 1;
sphere->triangles[nbT+1][2] = i_sauv;
nbT += 2;
}
// les triangles du haut
for(nbV=0; nbV<nvertices; nbV++) {
sphere->triangles[nbT][0] = nv-2;
sphere->triangles[nbT][1] = ( (nvertices-1) * nvertices) + 1 + nbV;
sphere->triangles[nbT][2] = ( (nvertices-1) * nvertices) + nbV;
nbT++;
}
// les triangles du bas
for(nbV=0; nbV<nvertices; nbV++) {
sphere->triangles[nbT][0] = nv-1;
sphere->triangles[nbT][1] = nvertices * nvertices + nbV;
sphere->triangles[nbT][2] = nvertices * nvertices + 1 + nbV;
nbT++;
}
} |
J'ai trouvé sinon l'équation paramétrique d'un sphère mais je ne sais pas comment l'utiliser
x = R cos u cos v
y = R cos u sin v
z = R sin u
peut etre que les paramètres passés à la fonction init ne sont pas bien choisis
Re: triangulation d'une sphere
Salut,
Citation:
Envoyé par lalaurie40
je cherche à modéliser une sphère en 3D par triangulation mais j'ai quelques problèmes d'algo.
et c'est quoi les problèmes au juste?
Je n'ai pas lu ton code, je suis allergique aux romans en C... (surtout dans le forum algorithmes)
Une méthode simple que tu peux utiliser est de découper ta sphère grâce à des parallèles (comme tes disques superposés) et des méridiens. Ca te définit des carrés (sauf aux pôles où tu as directement des triangles). Il ne reste plus qu'à diviser chaque carré en deux triangles. Eventuellement si tu veux que ce soit plus "joli", tu fais tourner chaque parallèle d'une demi largeur de carré autour de l'axe des pôles à la fin.