Created
October 19, 2011 14:10
-
-
Save cloderic/1298395 to your computer and use it in GitHub Desktop.
Point in triangle test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct Vector2 | |
{ | |
double x; | |
double y; | |
}; | |
struct Triangle2 | |
{ | |
Vector2 v[3]; | |
}; | |
double signedArea(const Vector2& apex, const Vector2& p1, const Vector2& p2) | |
{ | |
return (p1.x - apex.x) * (p2.y - apex.y) - (p1.y - apex.y) * (p2.x - apex.y); | |
}; | |
bool contains(const Triangle2& t, const Vector2& p, double precision = 0.00001) | |
{ | |
//e0 is the triangle's edge from its first to its second vertex. | |
//e1 is the triangle's edge from its second to its third vertex. | |
//e2 is the triangle's edge from its third to its first vertex. | |
double sign0 = signedArea(t.v[0],t.v[1],p); | |
double sign1 = signedArea(t.v[1],t.v[2],p); | |
if (sign0 > precision) | |
{ | |
if (sign1 < -precision) | |
{ | |
return false; // right of e0, left of e1 | |
} | |
else | |
{ | |
double sign2 = signedArea(t.v[2],t.v[0],p); | |
if (sign2 < -precision) | |
{ | |
return false; // right of e0, right of/aligned with e1, left of e2 | |
} | |
else | |
{ | |
return true; // right of e0, right of/aligned with e1, right of/aligned with e2 | |
} | |
} | |
} | |
else if (sign0 < -precision) | |
{ | |
if (sign1 > precision) | |
{ | |
return false; // left of e0, right of e1 | |
} | |
else | |
{ | |
double sign2 = signedArea(t.v[2],t.v[0],p); | |
if (sign2 > precision) | |
{ | |
return false; // left of e0, left of/aligned with e1, right of e2 | |
} | |
else | |
{ | |
return true; // left of e0, left of/aligned with e1, right of/aligned with e2 | |
} | |
} | |
} | |
else | |
{ | |
double sign2 = signedArea(t.v[2],t.v[0],p); | |
if (sign1 > precision) | |
{ | |
if (sign2 < -precision) | |
{ | |
return false; // aligned with e0, right of e1, left of e2 | |
} | |
else | |
{ | |
return true; // aligned with e0, right of e1, right of/aligned with e2 | |
} | |
} | |
else if (sign1 < -precision) | |
{ | |
if (sign2 > precision) | |
{ | |
return false; // aligned with e0, left of e1, right of e2 | |
} | |
else | |
{ | |
return true; // aligned with e0, left of e1, left of/aligned with e2 | |
} | |
} | |
else | |
{ | |
if (sign2 > precision) | |
{ | |
return true; // aligned with e0, aligned with e1, right of e2 | |
} | |
else if (sign2 < -precision) | |
{ | |
return true; // aligned with e0, aligned with e1, left of e2 | |
} | |
else | |
{ | |
// aligned with e0, aligned with e1, aligned with e2 | |
// t is a degenerate triangle, either sliver or point | |
double dot0 = (t.v[1].x - p.x) * (t.v[0].x - p.x) + (t.v[1].y - p.y) * (t.v[0].y - p.y); | |
if (dot0 <= precision) | |
{ | |
return true; // belong to e0 | |
} | |
else | |
{ | |
double dot1 = (t.v[2].x - p.x) * (t.v[1].x - p.x) + (t.v[2].y - p.y) * (t.v[1].y - p.y); | |
if (dot1 <= precision) | |
{ | |
return true; // belong to e1 | |
} | |
else | |
{ | |
return false; // outside of e0 and e1 | |
} | |
} | |
} | |
} | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment