quad.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. #include <assert.h>
  2. int intersectQuadPoint2(vec2 p, vec2 q[4]) {
  3. Vector2 outp;
  4. Vector2 outd;
  5. // two barycentric coordinate calculations
  6. vec2 a = q[1];
  7. vec2 b = q[0];
  8. vec2 c = q[2];
  9. vec2 d = q[3];
  10. vec2 ab = vSub(b, a);
  11. vec2 ac = vSub(c, a);
  12. vec2 ap = vSub(p, a);
  13. float invden_a = 1.f / (ab.x * ac.y - ac.x * ab.y);
  14. outp.x = (ap.x * ac.y - ac.x * ap.y) * invden_a;
  15. outp.y = (ab.x * ap.y - ap.x * ab.y) * invden_a;
  16. // see if p's coords are inside the triangle and less than d's
  17. if(outp.x < 0 || outp.y < 0) return C3DLAS_DISJOINT;
  18. vec2 db = vSub(b, d);
  19. vec2 dc = vSub(c, d);
  20. vec2 dp = vSub(p, d);
  21. float invden_d = 1.f / (db.x * dc.y - dc.x * db.y);
  22. outd.x = (dp.x * dc.y - dc.x * dp.y) * invden_d;
  23. outd.y = (db.x * dp.y - dp.x * db.y) * invden_d;
  24. // see if p's coords are inside the triangle and less than d's
  25. if(outd.x < 0 || outd.y < 0) return C3DLAS_DISJOINT;
  26. return C3DLAS_INTERSECT;
  27. }
  28. void intersectQuadPoint2_precalc(vec2 q[4], struct intersectQuadPoint2_precalc* pc) {
  29. // two barycentric coordinate calculations
  30. vec2 a = q[1];
  31. vec2 b = q[0];
  32. vec2 c = q[2];
  33. vec2 d = q[3];
  34. pc->a = a;
  35. pc->d = d;
  36. pc->ab = vSub(b, a);
  37. pc->ac = vSub(c, a);
  38. pc->db = vSub(b, d);
  39. pc->dc = vSub(c, d);
  40. pc->invden_a = 1.f / (pc->ab.x * pc->ac.y - pc->ac.x * pc->ab.y);
  41. pc->invden_d = 1.f / (pc->db.x * pc->dc.y - pc->dc.x * pc->db.y);
  42. }
  43. int intersectQuadPoint2_withprecalc(vec2 p, struct intersectQuadPoint2_precalc* pc) {
  44. vec2 ap = vSub(p, pc->a);
  45. if((ap.x * pc->ac.y - pc->ac.x * ap.y) * pc->invden_a < 0) return C3DLAS_DISJOINT;
  46. if((pc->ab.x * ap.y - ap.x * pc->ab.y) * pc->invden_a < 0) return C3DLAS_DISJOINT;
  47. vec2 dp = vSub(p, pc->d);
  48. if((dp.x * pc->dc.y - pc->dc.x * dp.y) * pc->invden_d < 0) return C3DLAS_DISJOINT;
  49. if((pc->db.x * dp.y - dp.x * pc->db.y) * pc->invden_d < 0) return C3DLAS_DISJOINT;
  50. return C3DLAS_INTERSECT;
  51. }