seting normals for a torus

I found code to draw my torus but it does light it and I am having some problems with my normals. Can somebody help me out or suggest another torus equation.
here’s the code:
var
i, j, k: integer;
s, t, x, y, z, twopi: double;
numc,numt:integer;
begin
numc:=64;numt:=64;
twopi := 2 * 3.14159;
for i := 0 to numc do
begin
for j := 0 to numt do
begin
for k := 1 downto 0 do
begin
s := (i + k) mod numc + 0.5;
t := j mod numt;
theTorus[i][j][k][0] := (1+(1-0.75)cos(stwopi/numc))cos(ttwopi/numt);
theTorus[i][j][k][1] := (1+(1-0.75)cos(stwopi/numc))sin(ttwopi/numt);
theTorus[i][j][k][2] := (1-0.75) * sin(s * twopi / numc);

			 end;
		end;
 end;

creates a torus with 64 sections and 64pieces to each section.

here’s the normal stuff:
procedure calcNormal(x,y,z:integer);
var
p1: array [0…2] of Double;
p2: array [0…2] of Double;
v1: array [0…2] of Double;
v2: array [0…2] of Double;
normal: array [0…2] of Double;
begin
//calc point 1
p1[0] := theTorus[x+1][y][z][0];
p1[1] := theTorus[x+1][y][z][1];
p1[2] := theTorus[x+1][y][z][2];

	//calc point 2
	p2[0] := theTorus[x][y+1][z][0];
	p2[1] := theTorus[x][y+1][z][1];
	p2[2] := theTorus[x][y+1][z][2];

	//calc v1
	v1[0]:=(p1[0]-theTorus[x][y][z][0]);
	v1[1]:=(p1[1]-theTorus[x][y][z][1]);
	v1[2]:=(p1[2]-theTorus[x][y][z][2]);

	//calc v2
	v2[0]:=(p2[0]-theTorus[x][y][z][0]);
	v2[1]:=(p2[1]-theTorus[x][y][z][1]);
	v2[2]:=(p2[2]-theTorus[x][y][z][2]);

	//calc normal
	normal[0] := (v1[1]*v2[2])-(v1[2]*v2[1]);
	normal[1] := (v1[0]*v2[2])-(v1[2]*v2[0]);
	normal[2] := (v1[0]*v2[1])-(v1[1]*v2[0]);

	//set normal
	glNormal3fv(@normal);
end;

Any assistance would be greatly appreciated

You can always call glutSolidTorus or glutWireTorus and built them into a display list for faster rendering.

Requires the GLUT library though.

I tried that. I was having trouble with running glut in delphi. I found another equation which was a little more comprihensive and easier to calculate the normals (they are a vector from the midradius out through the point). thanks anyway

The way above is practically the only way you can build a torus not using glut. The way to set the normals is to normally calculate the normal for every face. After you have done this:

for every point in torus

check if point is closer to torus-
middle than the middel-point of the ring is.
If so, point is in the middle of the
torus ring. The normal of this point needs to be inverted

next point

hope this helps,

Edo

Originally posted by edotorpedo:
[b]The way above is practically the only way you can build a torus not using glut. The way to set the normals is to normally calculate the normal for every face. After you have done this:

for every point in torus

check if point is closer to torus-
middle than the middel-point of the ring is.
If so, point is in the middle of the
torus ring. The normal of this point needs to be inverted

next point
[/b]

Try searching for quadrics on the web, it’s basically a quadratic equation that you can get to create different shapes (spheres, cylinders, cones torii etc) and has easy evaluation of the surface normal at every point. If there’s nothing on the web try looking it up in a computer gfx textbook or maybe a book on analytic geometry.

I did find one that was a little more intuative. It only had 2 for loops instead of 3 and it was easier to calculate the normal. the algorithm drew a series of circles as it went around a circle. And the normal of any given point is simply a ray passing from the center of the minor circle out through that point.

Here is the code I use to load up arrays for drawing a torus.
A torus is characterized by two radii – this code refers to them as core_radius and meridian_radius. All the rest of this should be straightforward.

for(int j = 0; j < J; j++)
for(int i = 0; i < I; i++)
{
float u = i/(I-1.0);
float v = j/(J-1.0);
float theta = u * 2.0 * M_PI;
float rho = v * 2.0 * M_PI;
float x = core_radiuscos(theta) + meridian_radiuscos(theta)cos(rho);
float y = core_radius
sin(theta) + meridian_radius*sin(theta)cos(rho);
float z = meridian_radius
sin(rho);
float nx = cos(theta)*cos(rho);
float ny = sin(theta)*cos(rho);
float nz = sin(rho);
float s = u;
float t = v;
// then, do fill in the appropriate arrays…
}

cass, I think I found your code and that’s what I used in my program, translated for delphi