triangle.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. Vector3 baryCoords2(Vector2 p, Vector2 a, Vector2 b, Vector2 c) {
  2. vec2 ab = vSub(b, a);
  3. vec2 ac = vSub(c, a);
  4. vec2 ap = vSub(p, a);
  5. float invden = 1.f / (ab.x * ac.y - ac.x * ab.y);
  6. Vector3 out;
  7. out.y = (ap.x * ac.y - ac.x * ap.y) * invden;
  8. out.z = (ab.x * ap.y - ap.x * ab.y) * invden;
  9. out.x = 1.0f - out.y - out.z;
  10. return out;
  11. }
  12. // returns the *signed* area of a triangle. useful for determining winding
  13. // positive values mean a clockwise triangle
  14. float triArea2p(Vector2* a, Vector2* b, Vector2* c) {
  15. return 0.5 * (
  16. ((b->x - a->x) * (b->y + a->y)) +
  17. ((c->x - b->x) * (c->y + b->y)) +
  18. ((a->x - c->x) * (a->y + c->y)));
  19. }
  20. // determines if a point is inside a triangle
  21. int triPointInside2p(Vector2* p, Vector2* a, Vector2* b, Vector2* c) {
  22. int d = signbit((p->x - b->x) * (a->y - b->y) - (a->x - b->x) * (p->y - b->y));
  23. int e = signbit((p->x - c->x) * (b->y - c->y) - (b->x - c->x) * (p->y - c->y));
  24. if(d != e) return 0;
  25. int f = signbit((p->x - a->x) * (c->y - a->y) - (c->x - a->x) * (p->y - a->y));
  26. return e == f;
  27. }
  28. float distLine2Triangle2(Line2 a, Vector2 tri[3]) {
  29. // check the lines around the outside
  30. float d[3];
  31. for(int i = 0; i < 3; i++) {
  32. d[i] = distLine2Line2(a, (Line2){tri[i], tri[(i + 1) % 3]});
  33. if(d[i] == 0) return 0;
  34. }
  35. // check if the line is entirely inside the triangle,
  36. // if one point (and therefore both points) is inside
  37. if(triPointInside2p(&a.start, tri, tri + 1, tri + 2)) {
  38. return 0;
  39. }
  40. // the line is outside; one of the corners is closest, find which one
  41. return MIN(MIN(d[0], d[1]), d[2]);
  42. }
  43. float distPoint2Triangle2(Vector2 a, Vector2 tri[3]) {
  44. // check if the point is inside the triangle,
  45. if(triPointInside2p(&a, tri, tri + 1, tri + 2)) {
  46. return 0;
  47. }
  48. // check the lines around the outside
  49. float d[3];
  50. for(int i = 0; i < 3; i++) {
  51. d[i] = vDistPointLine2(a, (Line2){tri[i], tri[(i + 1) % 3]});
  52. if(d[i] == 0) return 0;
  53. }
  54. // the point is outside; one of the corners is closest, find which one
  55. return MIN(MIN(d[0], d[1]), d[2]);
  56. }