How to Calculate Polygon Normal?

This looks like a stupid question :stuck_out_tongue:

I want to calculate the surface normal of a polygon with arbitrary vertices. Up till now I’ve implemented a function that calculates the surface normal of triangles only:

 
Vector3D Mesh3D::CalculateNormal(Face& polygon) const	// calculates the normal of the polygon
{
	if(polygon.verticesnum < 3)
#ifdef _CONSOLE
		fprintf(stderr,"
Error [Mesh3D::CalculateNormal]: Found polygon with less than 3 vertices...");
#else
		MessageBox(NULL,"Error [Mesh3D::CalculateNormal]: Found polygon with less than 3 vertices...","Error",MB_ICONERROR | MB_OK);
#endif
	
	// Create two 3D Vectors that share a common polygon vertex

	// polygon vertices references
	Vertex pv[3];	// we only need 3 vertices for normal calculation

	for(int i = 0; i < 3; i++)
		pv[i] = this->vertices[polygon.vertexindices[i]];

	// p1 = -p1
	pv[0] = this->Vector3DScalarMultiplication(pv[0],-1.0);

	// v1 = p2 + (-p1) = p2 - p1
	Vector3D v1 = this->Vector3DAddition(pv[1],pv[0]);

	// v2 = p3 + (-p1) = p3 - p1
	Vector3D v2 = this->Vector3DAddition(pv[2],pv[0]);

	// Calculate the cross product of v1,v2
	// which is a perpedicular vector to the plane
	// defined by v1, v2
	Vector3D normal = this->CrossProduct(v1, v2);

	// Normalize the length (0 <= length <= 1)
	normal = this->Normalize(normal);

	return normal;
}
 

I know this function is lame and I’d like some suggestions on how to calculate the normal of a polygon with more than 3 vertices. Thanks in advance for any help.

Just use any 3 vertices, for example the first three. It doesn’t matter which ones, because all vertices have be coplanar for the polygon to be valid.

Hi, I use this and it works well. Basically, it’s Newell’s method from the white book.

for (i=0, j = 1; i<faceVtxCount; i++, j++)
{
	if (j == faceVtxCount) j = 0;
	normal.x += (((vertexArray[faceVertexIndx[i]].z) + (vertexArray[faceVertexIndx[j]].z)) *
		 ((vertexArray[faceVertexIndx[j]].y) - (vertexArray[faceVertexIndx[i]].y)));
	normal.y += (((vertexArray[faceVertexIndx[i]].x) + (vertexArray[faceVertexIndx[j]].x)) *
		 ((vertexArray[faceVertexIndx[j]].z) - (vertexArray[faceVertexIndx[i]].z)));
	normal.z += (((vertexArray[faceVertexIndx[i]].y) + (vertexArray[faceVertexIndx[j]].y)) *
		 ((vertexArray[faceVertexIndx[j]].x) - (vertexArray[faceVertexIndx[i]].x)));
}
 

Hello there
Well its quite simple. Take any three vertices make sure that you are following a consistent winding order; either clockwise or anti clockwise. Create two new vectors by subtracting the second vertex from the first and then the third from the first. Then do a simple cross product between the two new vectors.
Here is the pseudocode.

 
Vector GetNormal(Vector v1, Vector v2, Vector v3)
{
   Vector a,b;
   a = v1 - v2;
   b = v1 - v3;
   return Cross(a,b);   
}

Hope this helps.
Thanx
MMMovania

im not sure what is polygon normal really is. afaik, it is either surface normal or vertex normal.

if its surface normal, MMMovania has explained it. and by the way, it is recommended that you normalize it before using it especially if you want to apply opengl lighting for the polygons.

if its vertex normal, find the average of every neighbouring surface normals for the corresponding vertices.

hope this helps.