Difference between revisions of "Calculating a Surface Normal"

From OpenGL.org
Jump to: navigation, search
m (Newell's Method: shorter lines to fit in the browser window)
Line 36: Line 36:
 
Begin Function CalculateSurfaceNormal (Input Polygon) Returns Vector
 
Begin Function CalculateSurfaceNormal (Input Polygon) Returns Vector
  
        Set Vertex Normal to (0, 0, 0)
+
  Set Vertex Normal to (0, 0, 0)
  
Begin Cycle for Index in [0, Polygon.vertexNumber)
+
  Begin Cycle for Index in [0, Polygon.vertexNumber)
  
                Set Vertex Current to Polygon.verts[Index]
+
      Set Vertex Current to Polygon.verts[Index]
                Set Vertex Next    to Polygon.verts[(Index plus 1) mod Polygon.vertexNumber]
+
      Set Vertex Next    to Polygon.verts[(Index plus 1) mod Polygon.vertexNumber]
  
                Set Normal.x to Sum of Normal.x and (multiply (Current.y minus Next.y) by (Current.z plus Next.z)
+
      Set Normal.x to Sum of Normal.x and (multiply (Current.y minus Next.y) by (Current.z plus Next.z)
                Set Normal.y to Sum of Normal.y and (multiply (Current.z minus Next.z) by (Current.x plus Next.x)
+
      Set Normal.y to Sum of Normal.y and (multiply (Current.z minus Next.z) by (Current.x plus Next.x)
                Set Normal.z to Sum of Normal.z and (multiply (Current.x minus Next.x) by (Current.y plus Next.y)
+
      Set Normal.z to Sum of Normal.z and (multiply (Current.x minus Next.x) by (Current.y plus Next.y)
  
        End Cycle
+
  End Cycle
  
Returning Normalize(Normal)
+
  Returning Normalize(Normal)
  
 
End Function
 
End Function

Revision as of 06:15, 22 July 2010

Algorithm

A surface normal for a triangle can be calculated by taking the vector cross product of two edges of that triangle. The order of the vertices used in the calculation will affect the direction of the normal (in or out of the face w.r.t. winding).

So for a triangle p1, p2, p3, if the vector U = p2 - p1 and the vector V = p3 - p1 then the normal N = U X V and can be calculated by:

Nx = UyVz - UzVy

Ny = UzVx - UxVz

Nz = UxVy - UyVx

Pseudo-code

Given that a vector is a structure composed of three floating point numbers and a Triangle is a structure composed of three Vectors, based on the above definitions:

Begin Function CalculateSurfaceNormal (Input Triangle) Returns Vector

	Set Vector U to (Triangle.p2 minus Triangle.p1)
	Set Vector V to (Triangle.p3 minus Triangle.p1)

	Set Normal.x to (multiply U.y by V.z) minus (multiply U.z by V.y)
	Set Normal.y to (multiply U.z by V.x) minus (multiply U.x by V.z)
	Set Normal.z to (multiply U.x by V.y) minus (multiply U.y by V.x)

	Returning Normal

End Function

Newell's Method

Also you can use a Newell's method for an arbitrary 3D polygon.

Begin Function CalculateSurfaceNormal (Input Polygon) Returns Vector

   Set Vertex Normal to (0, 0, 0)

   Begin Cycle for Index in [0, Polygon.vertexNumber)

      Set Vertex Current to Polygon.verts[Index]
      Set Vertex Next    to Polygon.verts[(Index plus 1) mod Polygon.vertexNumber]

      Set Normal.x to Sum of Normal.x and (multiply (Current.y minus Next.y) by (Current.z plus Next.z)
      Set Normal.y to Sum of Normal.y and (multiply (Current.z minus Next.z) by (Current.x plus Next.x)
      Set Normal.z to Sum of Normal.z and (multiply (Current.x minus Next.x) by (Current.y plus Next.y)

   End Cycle

   Returning Normalize(Normal)

End Function