Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

What's a reliable way to calculate a 2D normal vector for each edge of a triangle, so that each normal is pointing outwards from the triangle?

To clarify, given any triangle - for each edge (e.g p2-p1), I need to calculate a 2D normal vector pointing away from the triangle at right angles to the edge (for simplicity we can assume that the points are being specified in an anti-clockwise direction).

I've coded a couple of hacky attempts, but I'm sure I'm overlooking some simple method and Google isn't being that helpful today - that and I haven't had my daily caffeine yet!

share|improve this question

2 Answers 2

up vote 5 down vote accepted

This answer is for when the winding is unknown. As the question is now phrased, simply calculating the edge normal directly is entirely sufficient and trivial.

So, say you are trying to find the normal for edge AB. Take the normal (AB.y, -AB.x). Now dot this normal with the vector AC. If the result is positive, then the normal is facing towards the "inner" half-space, so invert the normal.

ex:

A = (3,4)
B = (2,1)
C = (1,3)

AB = (2,1) - (3,4) = (-1,-3)
AC = (1,3) - (3,4) = (-2,-1)
N = n(AB) = (-3,1)
D = dot(N,AC) = 6 + -1 = 5

since D > 0:
  N = -N = (3,-1)

You could also use the "2D cross product" (treat each vector as if it were a 3D vector with a Z component of zero) between AB and AC, test if the resulting Z component were positive or negative, and then take the RHS or LHS normal respectively of AB. I find the dot product approach to be simpler.

share|improve this answer
    
If this is going to be the accepted answer, please at least remove all the useless computations (AC, D) and the useless final test. Knowing the triangle winding ensures that it is never necessary to test the dot product. –  Sam Hocevar Apr 7 '12 at 14:44
    
The assumption clearly stated in the answer is that this works if you dont know the winding. The question appears to have changed since I answered (or I was dumb and missed it), so please change the selected answer rather than the answer itself. I'll add a louder note about when this is applicable, at least. –  Sean Middleditch Apr 7 '12 at 22:33

Here is a method that works:

  • get a vector normal to the triangle, for instance p1p2 ^ p1p3
  • for each edge, take the result of its cross product with that vector
  • normalize

If your triangles are in a 2D space, you can use (0 0 1) as the normal vector and the results are (assuming p1 has coordinates (x1 y1) etc.):

edgenormal(p1p2) = normalize(vec2(y2 - y1, x1 - x2))
edgenormal(p2p3) = normalize(vec2(y3 - y2, x2 - x3))
edgenormal(p3p1) = normalize(vec2(y1 - y3, x3 - x1))

This is assuming p1p2p3 is anticlockwise.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.