I saw the following code to make an icosahedron from the link http://www.glprogramming.com/red/chapter02.html
#define X .525731112119133606
#define Z .850650808352039932
static GLfloat vdata[12][3] = {
{-X, 0.0, Z}, {X, 0.0, Z}, {-X, 0.0, -Z}, {X, 0.0, -Z},
{0.0, Z, X}, {0.0, Z, -X}, {0.0, -Z, X}, {0.0, -Z, -X},
{Z, X, 0.0}, {-Z, X, 0.0}, {Z, -X, 0.0}, {-Z, -X, 0.0}
};
static GLuint tindices[20][3] = {
{0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1},
{8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3},
{7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6},
{6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11} };
int i;
glBegin(GL_TRIANGLES);
for (i = 0; i < 20; i++) {
/* color information here */
glVertex3fv(&vdata[tindices[i][0]][0]);
glVertex3fv(&vdata[tindices[i][1]][0]);
glVertex3fv(&vdata[tindices[i][2]][0]);
}
glEnd();
The array tindices[][] tells how to link the vertices to make triangles. For example, the first triangle is made from the zeroth, fourth, and first vertex. If you take the vertices for triangles in the order given, all the triangles have the same orientation.
But how can I know whether or not all the triangles will have the same orientation just by observing the code? For having the same orientation, the way in which all triangles are made must be clockwise or all anticlockwise, right?Then, shouldn`t I make up a complex structure in my mind just to know whether or not they have the same orientation? Even if I observed that the orientation are the same given in the code, how can I form(write) code for the orientation myself?
For relatively simple shapes, you can sketch them into a 3D coordinate system on a piece of paper. Label each vertex with an index, and start enumerating the triangles, making sure that they are all counter-clockwise when looking at the shape from the outside.
Mathematically, it's fairly easy for your example because it's a convex shape centered at the origin. So if you calculate the face normal of each triangle, it needs to point away from the origin. If the coordinate vectors of the 3 corners are v0 = (x0, y0, z0)
, v1 = (x1, y1, z1)
and v2 = (x2, y2, z2)
, the face normal can be calculated as the cross product of v1 - v0
and v2 - v0
:
[ x1 - x0 ] [ x2 - x0 ] [ (y1 - y0) * (z2 - z0) - (z1 - z0) * (y2 - y0) ]
[ y1 - y0 ] x [ y2 - y0 ] = [ (z1 - z0) * (x2 - x0) - (x1 - x0) * (z2 - z0) ]
[ z1 - z0 ] [ z2 - z0 ] [ (x1 - x0) * (y2 - y0) - (y1 - y0) * (x2 - x0) ]
To figure out if this vector points away from the origin, we calculate the dot product with one of the vertices, e.g. v0
. This dot product will have to be positive for the triangle to be counter-clockwise:
x0 * ((y1 - y0) * (z2 - z0) - (z1 - z0) * (y2 - y0)) +
y0 * ((z1 - z0) * (x2 - x0) - (x1 - x0) * (z2 - z0)) +
z0 * ((x1 - x0) * (y2 - y0) - (y1 - y0) * (x2 - x0))
I'll save you from the simple algebra of multiplying out the terms and combining them. Most of them end up dropping out, and the simplified result is:
x0 * y1 * z2
- x0 * y2 * z1
+ x2 * y0 * z1
- x1 * y0 * z2
+ x1 * y2 * z0
- x2 * y1 * z0
If this looks familiar, that's no accident. It's indeed the determinant of the matrix:
[ x0 y0 z0 ]
[ x1 y1 z1 ]
[ x2 y2 z2 ]
This makes sense, because the sign of this determinant tells you if the vectors v0
, v1
, v2
have a right-handed orientation, which is exactly what we were looking for in the first place.
Applying this to the first triangle of your example, which consists of vertices 0, 4, 1:
[ -X 0.0 Z ]
det [ 0.0 Z X ] = - X * Z * Z - X * Z * Z = - 2 * X * Z * Z
[ X 0.0 Z ]
Second triangle, consisting of vertices 0, 9, 4:
[ -X 0.0 Z ]
det [ -Z X 0.0 ] = - X * X * X - Z * Z * Z
[ 0.0 Z X ]
Third triangle, consisting of vertices 9, 5, 4:
[ -Z X 0.0 ]
det [ 0.0 Z -X ] = - X * Z * Z - X * Z * Z = - 2 * X * Z * Z
[ 0.0 Z X ]
All these determinants have negative values, so at least your first 3 triangles all have clockwise orientation.