Reputation: 71
I was making a ray tracer in c++ and was coming across an issue when I downloaded objects because it would only render some of the triangles because they were drawn counter-clockwise.
I looked up this being an issue since it would be back facing. But Im confused on how you are actually supposed to know just by the vertices. If anyone could help me make a function to take in three vectors for each point of the triangle and reorder them so that It would be drawn clockwise.
Thank you.
Upvotes: 3
Views: 350
Reputation: 36682
You can calculate the signed area formed by the triangle defined by the three points - this is equivalent to the 2D 'cross product' of the vectors representing the edges (sometimes called perp product):
Here is a naive implementation in python that shows the calculation; you can transcribe it to C++ at your leisure.
From there, swapping the position of two points in the triangle will invert the turn from ccw
to cw
, and vice-versa
class CollinearpointsError(ValueError):
pass
def ccw(triangle):
"""returns True if the triangle points are counter clock wise,
False otherwise, and raises a CollinearpointsError when the
three points are collinear
"""
A, B, C = triangle
ax, ay = A
bx, by = B
cx, cy = C
AB = (bx - ax, by - ay)
AC = (cx - ax, cy - ay)
a, b = AB
c, d = AC
signed_area_x2 = a * d - b * c
if signed_area == 0:
raise CollinearpointsError('the three points are collinear')
return (a * d - b * c) > 0
def cw(triangle):
"""returns True if the triangle points are clock wise,
False otherwise, and raises a CollinearpointsError when the
three points are collinear
"""
return not ccw(triangle)
A = (0, 0)
B = (0, 1)
C = (1, 0)
triangle = (A, B, C)
print(cw(triangle))
triangle = (A, C, B)
print(cw(triangle))
triangle = (A, B, (0, 2))
print(cw(triangle))
True
False
CollinearpointsError: the three points are collinear
Upvotes: 2