# How do I generate a torus mesh?

I'm trying to programmatically generate vertices and indices for a torus. I found this piece of code somewhere, and it looks like it works, but I'm not certain it is correct.

With my little knowledge of trigonometry, I figured out how the vertex generation part works, but I'm stuck at the index buffer part (though I know what the modulus operator is used for).

Does the code work correctly? Can anyone explain what it does to generate the correct indices?

I tried to output the index buffer and noticed there's a triangle with indices `(10,10,10)`, which is weird and makes me think this may be wrong. Plus the UVs look weird for the last 'slice' of the torus, as in this pic.

``````int sides = 10, cs_sides = 40;
float radius = 3.5 * 10.0;
float cs_radius = 0.75 * 10.0;

numVertices = sides * cs_sides;
Vertices = malloc(sizeof(Vertex) * numVertices);

numIndices = (2 * ((sides+1) * cs_sides) + cs_sides);
Indices = malloc(sizeof(GLushort) * numIndices);

int angleincs = 360/sides;
int cs_angleincs = 360/cs_sides;

//calculating the vertex array
for (int j=0, m=0; j<360; j+=cs_angleincs, m++)
{
zval = cs_radius * sinf(j * D_TO_R );

int index = (m*sides);
for (int i=0, n=0; i<360; i+=angleincs, n++)
{
Vertices[index + n].Position[0] = currentradius * cosf(i * D_TO_R ); // x
Vertices[index + n].Position[1] = currentradius * sinf(i * D_TO_R ); // y
Vertices[index + n].Position[2] = zval;                              // z

Vertices[index + n].Color[0] = 1.0;
Vertices[index + n].Color[1] = 0.0;
Vertices[index + n].Color[2] = 0.0;
Vertices[index + n].Color[3] = 1.0;

float u = (float)i/sides;
float v = ((float)j + u)/cs_sides;

Vertices[index + n].TexCoord[0] = u;
Vertices[index + n].TexCoord[1] = v;
}
}

// cs_sides = 40
// sides = 10

int i=0, n=0;
//calculating the index array
for (;i<cs_sides; i++) {
for (int j=0; j<sides; j++) {
Indices[n++] = i * sides + j;
Indices[n++] = ((i+1) % cs_sides) * sides + j;
}

Indices[n++] = i * sides;
Indices[n++] = ((i+1)%cs_sides) * sides;
Indices[n++] = ((i+1)%cs_sides) * sides;
}
``````
-

I'll avoid even looking at your code and instead simply explain how to build a torus.

To understand fully what I will say, you need to know some basic vector algebra:

1. vectors sums: X:=(x1,x2,x3), Y:=(y1,y2,y3); X + Y=(x1+y1, x2+y2, x3+y3)
2. scalar multiplication: X:=(x1,X2,x3); a·X = (a·x1, a·x2, a·x3)
3. norm: |X| = √(x1·x1 + x2·x2 + x3·x3)
4. [optional] scalar product: X·Y= (x1·y1 + x2·y2 + x3·y3) so |X|² = X·X

Our Torus will be centered on C, its first diameter (d) will be parallel to the XY plane and the second diameter will be d': we will use u to run on the first circle and v to run to the second cicle so both u and v will go from 0 to 2π.

As you see, we use u to compute the point P on the circle centered on C. We now need to construct a second circle like this that is centered on P and parallel to the direction C->P. I hope this image explains what I mean:

The reddish circle is constructed same as the first, with a difference: the circle does not lies on a standard plane but on the plane parallel both to the Z axis and the C-->P direction (the segment lebeled d).

Lets think about the first circle: when we say

we are telling that

where X = (1,0,0), Y = (0,1,0), Z = (0,0,1): the "component adding".

We can do the same for the second cicle using P as center, discarding the third component (as it is zero), using the Z axis as for the sin component and the W axis for the cos component.

The W axis is simply an arbitrary axis that we construct so it is directed from C to P and has unitary length (as X, Y and Z were).

The norm of a vector is its length so we can define W as follows:

we take W' = P - C because it the vector that "moves" C to P ( C + W' = C + P - C = P); then we set W to have the direction of W' and the length of 1.

This is the result:

Now you have a way to compute the point Q in terms of u and v.

Noticing W is always (cos(u),sin(u),0), we can put it all together and write the function Q(u, v):

You can now construct your quads by connecting: (u, v) -> (u, v+1) -> (u-1, v+1) -> (u-1, v)

For triangles, only connect:

(u, v) -> (u, v+1) -> (u-1, v) and

(u-1, v) -> (u, v+1) -> (u-1, v+1)

(P.S. Doesn't your framework have some sort of torus primitive?)

-
Ciao! Thanks a lot for your explanation. It would be awesome if you could expand this and explain how to build the vertex and index buffers, because actually that's where I'm stuck (as I said in the question). Also note that I can't use quads as I'm using OpenGL ES. – pt2ph8 Sep 4 '11 at 12:38
I don't understand what is missing. You can compute the value for n x m points dividing the u range by n samples and the v range by m. Put every computed point into your vertex buffer and use a plain mapping to generate the index buffer as I explain. Remember that both u and v vary from 0 to 2 PI – FxIII Sep 4 '11 at 14:44
when i say (u,v) i mean the index of the vertex whit a given u and v so (u-1, v) means the previous vertex in u direction and (u, v+1) means the next vertex in v. – FxIII Sep 4 '11 at 14:47