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…
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 *)¢er);
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?