Skip to content

Instantly share code, notes, and snippets.

@cloderic
Created October 19, 2011 14:10
Show Gist options
  • Save cloderic/1298395 to your computer and use it in GitHub Desktop.
Save cloderic/1298395 to your computer and use it in GitHub Desktop.
Point in triangle test
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