PDA

View Full Version : seting normals for a torus



hermes
10-16-2000, 06:31 AM
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(s*twopi/numc))*cos(t*twopi/numt);
theTorus[i][j][k][1] := (1+(1-0.75)*cos(s*twopi/numc))*sin(t*twopi/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

Bob
10-17-2000, 03:07 AM
You can always call glutSolidTorus or glutWireTorus and built them into a display list for faster rendering.

Requires the GLUT library though.

hermes
10-17-2000, 04:04 PM
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

edotorpedo
10-18-2000, 12:28 AM
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

harsman
10-23-2000, 12:58 AM
Originally posted by edotorpedo:
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


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.

hermes
10-23-2000, 06:11 AM
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.

cass
10-23-2000, 06:56 AM
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_radius*cos(theta) + meridian_radius*cos(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...
}

hermes
10-23-2000, 10:48 AM
cass, I think I found your code and that's what I used in my program, translated for delphi