Please help! - using vectors to calculate normals

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++;

glBegin(GL_QUAD_STRIP);
for(int j=0;j<Sweep;j++)
{
	for(int i=0;i<=numr;i++)
	{
		ang1 = (j*dA1) * (PI/180);
		for(int p=0;p<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,
float meridian_radius, float core_radius,
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;
glBegin(GL_QUAD_STRIP);
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));
  	y = float(core_radius*sin(theta) + meridian_radius*sin(theta)*cos(rho));
  	z = float(meridian_radius*sin(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);

  	x = float(core_radius*cos(theta) + meridian_radius*cos(theta)*cos(rho2));
  	y = float(core_radius*sin(theta) + meridian_radius*sin(theta)*cos(rho2));
  	z = float(meridian_radius*sin(rho2));
  	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.