calculate the normals of all the triangles in an array of vertices

Hi…

I have an array of 36 vertices: cube[36][3]…

I’d like to write functions that compute normals for each individual triangle of the array…

How could I?

I need some code please…

Use vector cross product. If vertices are
v1,v2,v3 then the normal is
N = (v2 - v1) x (v3 - v1)
You’ll have to scale it down to length 1 also.

Welll… I know the basics… what I don’t know is how to apply it to programming…

Here are my functions…

void calculateNormals(float v[3][3], float n[3])
{
float v1[3], v2[3];
x=0; y=1; z=2;

v1[x] = v[0][x] - v[1][x];
v1[y] = v[0][y] - v[1][y];
v1[z] = v[0][z] - v[1][z];

v2[x] = v[1][x] - v[2][x];
v2[y] = v[1][y] - v[2][y];
v2[z] = v[1][z] - v[2][z];

n[x] = v1[y]*v2[z] - v1[z]*v2[y];
n[y] = v1[z]*v2[x] - v1[x]*v2[z];
n[z] = v1[x]*v2[y] - v1[y]*v2[x];

ReduceToUnit(n);

}

void ReduceToUnit(float vector[3])
{

Length=(float)sqrt((vector[0]*vector[0])+(vector[1]*vector[1])+(vector[2]*vector[2]));

if (Length==0.0f) Length = 1.0f;

vector[0] /= Length;
vector[1] /= Length;
vector[2] /= Length;
}

What I can’t get to do is… calculate the normals of the triangles of my object… The vertices of my object are stored in cube[36][3]…

How could I use the calculateNormals function to actually calculate all the normals of all the triangles of my object?..

Another thing is I don’t understand the arguments v[3][3] and n[3]…

And how could I draw these normals to check them out?

I gues my question is better written this time…

Many thanks…

First, use cube[3][36] instead of cube[36][3]. Then rewrite calculateNormals(float v[3][3], float n[3]) to calculateNormals(float v0[3], float v1[3], float v2[3], float n[3]).
Replace every v[0][x] with v0[x] … and the same with the others.
Then you can use it like calculateNormals(cube[7], cube[21], cube[14]) or whatever.

I tried what you told me… however I still don’t know how to use the function to compute the normals of all the triangles of my object… here are the changes I made…

First of all… this is how I use the function… does it compute the normal of the first triangle?:
calculateNormals( cube[0], cube[1], cube[2], normals);

I guess this compute the normal for the second triangle?:
calculateNormals( cube[1], cube[2], cube[3], normals);

By the way this is how I declared the variable normals: static float normals[3];
I guess it’s not big enough to store all the normals?

Here the two functions I use to calculate the normals:

void calculateNormals(float p0[3], float p1[3], float p2[3], float n[3])
{
float v1[3], v2[3];

x=0; y=1;	z=2;

//Vector offset
v1[x] = p0[x] - p1[x];
v1[y] = p0[y] - p1[y];
v1[z] = p0[z] - p1[z];

v2[x] = p1[x] - p2[x];
v2[y] = p1[y] - p2[y];
v2[z] = p1[z] - p2[z];

//Get normals: cross product of two vectors v1 and v2
n[x] = v1[y]*v2[z] - v1[z]*v2[y];
n[y] = v1[z]*v2[x] - v1[x]*v2[z];
n[z] = v1[x]*v2[y] - v1[y]*v2[x];

//normalize the vector (shorten to one)
ReduceToUnit(n);

}

void ReduceToUnit(float vector[3])
{
Length=(float)sqrt((vector[x]*vector[x])+(vector[y]*vector[y])+(vector[z]*vector[z]));

if (Length==0.0f) Length =1.0f;

vector[x] /= Length;
vector[y] /= Length;
vector[z] /= Length;

}

How could I draw the normal?

Many thanks

If the first triangle has vertices cube[0],cube[1] and cube[2] then calculateNormals( cube[0], cube[1], cube[2], normals[0]) places the normal to this triangle in the normals[0] array. You should make normals an array like
float normals[3][WHATEVER_NEEDED];

To draw the normal just draw a line from the vertex to vertex + normal.

Hi…

If I want calculate 12 normals of my cube(I have 12triangles)… I need to declare normals[3][12]… is that right?

Can you explain more in detais how to draw the normals please… I did not get it…

Many thanks

Yes, that’s right.
To draw the normal, say you have a vertex v and a normal n:
float v[3],n[3];

Your first point is (v[0],v[1],v[2]) and the other is (v[0] + k * n[0], v[1] + k * n[1], v[2] * k * n[2]) … you may perhaps need to scale the normal, so choose k suitable.

Thanks for the answer… What is k? (sorry if it is a stupid question!)

k is just a constant you can choose whatever you think is appropriate. You’ll probably not want normals that is too short to be seen or too long to fit on screen.

A simple question… How come a normal vector is only defined by x, y and z as it is not a point but a vector… I’m just a beginner…

Well … a vector is something that points out a direction and doesn’t have any kind of position.

Thanks to your help I managed to display the normals correctly… however, I’d like to draw them in the middle of the triangles… how can I?

Thanks

nico:
a vector express a direction and a magnitude. the direction is across the line from the origin (0,0,0) to the vector endpoint, the magnitude is the lenght of the vector.
a special vector is the unit vector, also called versor, wich has lenght =1, and in fact express only a direction.
so, normals are substantially versors.

a way to find the triangle baricenter is to average the the triangle vertices together.

in pseudocode:

center=(a+b+c)/3
endpoint=center+normalize(center)*NORMAL_LEN;

glBegin(GL_LINES);
glVertex3fv((float *)&center);
glVertex3fv((float *)&endpoint);
glEnd();

a,b,c are the triangle verts.
center,endpoint are your normal line endpoints.

i recommend you to write overloaded operators to work easily with vector operations

Dolo//\ightY

Many thanks for your replies…

I managed to draw the normal in the centre of the triangles… Cooooool…

My next step is to compare adjacent normals… in a way that if the angle between two adjacent normals is superior to a threeshold, then draw the edge shared by the two adjacent faces…

Many thanks

Any information on Quad-edge or Winged-edge data structure?