1
\$\begingroup\$

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!

\$\endgroup\$

2 Answers 2

5
\$\begingroup\$

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.

\$\endgroup\$
2
  • \$\begingroup\$ 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. \$\endgroup\$ Apr 7, 2012 at 14:44
  • \$\begingroup\$ 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. \$\endgroup\$ Apr 7, 2012 at 22:33
2
\$\begingroup\$

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.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .