Hello,

I am trying to draw a torus and need to calculate the normal for a particular point on the torus.

I sweep the radius ® around the Radial Path ® to draw the torus. At each point i calculate a vertex normal.

The torus is incorrectly shaded - please can someone have a look at the code and tell me what i’m doing wrong?

void CGLtoralSweep::Draw(float R, float r, int numr, int numR, float Sweep, GLenum mode)
{
/* dA1 = change in ang1
* dA2 = change in ang2
*/

``````float ang1,ang2;
float dA1 = 360/(numR*(360/Sweep));
float dA2 = 360/numr;
float CentreXYZ[3]; float CurrentXYZ[3]; float Normal[3];

Sweep = Sweep/dA1;
numr++;
numR++;

for(int j=0;j&lt;Sweep;j++)
{
for(int i=0;i&lt;=numr;i++)
{
ang1 = (j*dA1) * (PI/180);
for(int p=0;p&lt;2;p++)
{
ang2 = (i*dA2) * (PI/180);

CentreXYZ[0] = 0.0f;
CentreXYZ[1] = R*sin(ang1);
CentreXYZ[2] = R*cos(ang1);

CurrentXYZ[0] = r*sin(ang2);
CurrentXYZ[1] = (R + r*cos(ang2))* sin(ang1);
CurrentXYZ[2] = (R + r*cos(ang2))* cos(ang1);

CalculateVectorNormal(CentreXYZ,CurrentXYZ,Normal);

glNormal3f(Normal[0],Normal[1],Normal[2]);
glVertex3fv(CurrentXYZ);

ang1 = ang1 + (dA1 * (PI/180));
}
}
}
glEnd();
``````

}

void CGLobject::Normalise(float& v1, float& v2, float& v3)
{
/* get length of normal /
float val = (float) sqrt(v1
v1 + v2v2 + v3v3);

``````/* normalized the normal*/
v1 /= val; v2 /= val; v3 /= val;
``````

}

void CGLobject::Normalise(float v[3])
{
Normalise(v[0],v[1],v[2]);
}

void CGLobject::CalculateVectorNormal(float coord1[], float coord2[], float vr[])
{
vr[0] = coord1[1] * coord2[2] - coord2[1] * coord1[2];
vr[1] = coord2[0] * coord1[2] - coord1[0] * coord2[2];
vr[2] = coord1[0] * coord2[1] - coord2[0] * coord1[1];

Normalise(vr);
}

i really need to get this working. any help would be much appreciated,

kev.

Kev,

For tori you don’t need to calculate the normals using a forward difference scheme. The expression below calculates it directly.

void draw_torus(vertex_attributes & va,
int meridian_slices, int core_slices)
{
int J = meridian_slices;
int I = core_slices;
for(int j = 0; j < J-1; j++)
{
float v = j/(J-1.0f);
float rho = v * 2.0f * M_PI;
float v2 = (j+1)/(J-1.0f);
float rho2 = v2 * 2.0f * M_PI;
for(int i = 0; i < I; i++)
{
float u = i/(I-1.0f);
float theta = u * 2.0f * M_PI;
float x,y,z,nx,ny,nz;

``````  	x = float(core_radius*cos(theta) + meridian_radius*cos(theta)*cos(rho));
nx = float(cos(theta)*cos(rho));
ny = float(sin(theta)*cos(rho));
nz = float(sin(rho));

va.normal(nx, ny, nz);
va.texcoord(u,v);
va.position( x,  y,  z);

nx = float(cos(theta)*cos(rho2));
ny = float(sin(theta)*cos(rho2));
nz = float(sin(rho2));

va.normal(nx, ny, nz);
va.texcoord(u,v2);
va.position( x,  y,  z);
}
glEnd();
``````

}
}

[This message has been edited by cass (edited 06-09-2000).]

Thanks,

I can see where i was going wrong now.

Being as i have the centre coordinate and the coordinate for the point i’m drawing

i can achieve a normal by simply using:

``````			Normal[0] = CurrentXYZ[0] - CentreXYZ[0];
Normal[1] = CurrentXYZ[1] - CentreXYZ[1];
Normal[2] = CurrentXYZ[2] - CentreXYZ[2];
Normalise(Normal);
``````

I guess i got myself a little confused!

kev.