/src/Geometry_GeometricTests/BPT_AdditionalTests.cpp

http://github.com/Akranar/daguerreo · C++ · 163 lines · 35 code · 5 blank · 123 comment · 1 complexity · c6a447188114f63c614bdd1a8759f1c5 MD5 · raw file

  1. #include "BasicPrimitiveTests.h"
  2. #include "GeometricPrimitives.h"
  3. bool BasicPrimitiveTests::TestingPointInPolygon(const Eigen::Vector3f & point, const Polygon & polygon)
  4. {
  5. /*
  6. Main Idea:
  7. Binary Search Method:
  8. -> Uses binary search to find where in the polygon the point is in.
  9. Counting ray enter/exits:
  10. -> Shoots a ray from the point along an axis and counts how many times it enters and exits the polygon.
  11. */
  12. return false;
  13. }
  14. bool BasicPrimitiveTests::TestingPointInTriangle(const Eigen::Vector3f & point, const Triangle & triangle)
  15. {
  16. /*
  17. Main Idea:
  18. -> Translates both triangle and the point so the point is at the origin. Then test if the origin is contained in the triangle.
  19. General Idea:
  20. -> P lies inside ABC IFF
  21. -> Triangles PAB, PBC, PCA are all same winding (clockwise or counter-clockwise).
  22. Test:
  23. -> Since P is now origin:
  24. -> "General Idea" can be tested with:
  25. -> dot(u, v) >= 0 and
  26. -> dot(u, w) >= 0
  27. -> where u = cross(B, C)
  28. -> where v = cross(C, A)
  29. -> where w = cross(A, B)
  30. */
  31. return false;
  32. }
  33. bool BasicPrimitiveTests::TestingPointInPolyhedron(const Eigen::Vector3f & point, const Polyhedron & polyhedron)
  34. {
  35. /*
  36. Main Idea:
  37. Method 1:
  38. -> Test if the point is in each of the halfspaces defining the polyhedron.
  39. Method 2:
  40. -> Build BSP tree and see if point ends up in a solid leaf (Chapter 8)
  41. -> Polyhedron must be given as closed mesh.
  42. Method 3:
  43. -> GJK Method (Chapter 9)
  44. Method 4:
  45. -> Shoot a ray from point in any direction and count the number of faces intersected.
  46. */
  47. return false;
  48. }
  49. bool BasicPrimitiveTests::IntersectionOfTwoPlanes(const Plane & plane_a, const Plane & plane_b)
  50. {
  51. /*
  52. Main Idea:
  53. -> Construct the line that the planes intersect at.
  54. -> Let:
  55. -> Plane 1: dot(n1, X) = d1
  56. -> Plane 2: dot(n2, X) = d2
  57. -> L = P + t * d
  58. -> d = cross(n1, n2)
  59. -> Getting P:
  60. -> Since P is spanned by both n1 and n2
  61. -> P = k1 * n1 + k2 * n2
  62. -> P must lie on both plane 1 and plane 2
  63. -> Must satisfy both equations.
  64. -> Get system of equations:
  65. -> dot(n1, k1 * n1 + k2 * n2) = d_1
  66. -> dot(n2, k1 * n1 + k2 * n2) = d_2
  67. -> Solution:
  68. -> k1 = (d1 * dot(n2, n2) - d2 * dot(n1, n2)) / dot(n1, n1) * dot(n2, n2) - exp( dot(n1, n2) , 2 )
  69. -> k2 = (d2 * dot(n1, n1) - d1 * dot(n1, n2)) / dot(n1, n1) * dot(n2, n2) - exp( dot(n1, n2) , 2 )
  70. Optimization:
  71. -> Use Lagrange's Identity
  72. -> denom = dot(n1, n1) * dot(n2, n2) - exp( dot(n1, n2) , 2 )
  73. -> = dot(cross(n1, n2), cross(n1, n2))
  74. -> = dot(d, d)
  75. -> Use vector identity: cross(u, cross(v, w)) = dot(u, w) * v - dot(v, w) * u
  76. -> Simplify P = k1 * n1 + k2 * n2
  77. -> By substituting k1 and k2 + shitload of algebra
  78. -> P = cross(d1 * n2 - d2 * n1, d) / dot(d, d)
  79. -> where d = cross(n1, n2)
  80. */
  81. return false;
  82. }
  83. bool BasicPrimitiveTests::IntersectionOfThreePlanes(const Plane & plane_a, const Plane & plane_b, const Plane & plane_c)
  84. {
  85. /*
  86. Five Cases:
  87. (0) All three planes parallel/coplanar to one another.
  88. (1) All three intersect at single line.
  89. (2) Two planes parallel; Last plane intersects both.
  90. -> Forms two parallel intersection lines.
  91. (3) Planes pairwise intersect.
  92. -> Forms three parallel intersection lines.
  93. (4) All planes intersect at single point.
  94. Let:
  95. -> Planes 1-3:
  96. -> dot(ni, X) = di
  97. -> where i = 1, 2, 3
  98. Solving:
  99. -> Case 4:
  100. -> Identified by:
  101. -> Scalar Triple Product: [n1, n2, n3] = 0
  102. -> Other cases identified similarly.
  103. -> Intersect at point X = (x1, x2, x3)
  104. -> Solve as 3x3 system of linear equations using plane equations with Cramer's Rule.
  105. -> x1 = det( d, m2, m3 ) / denom
  106. -> x2 = det( m1, d, m3 ) / denom
  107. -> x3 = det( m1, m2, d ) / denom
  108. -> where m1 = (n1.x, n2.x, n3.x)
  109. -> where m2 = (n1.y, n2.y, n3.f)
  110. -> where m3 = (n1.z, n2.z, n3.z)
  111. -> where d = (d1, d2, d3)
  112. -> where denom = det( m1, m2, m3 )
  113. -> X simplifies to:
  114. -> x1 = dot(d, u) / denom
  115. -> x2 = dot(m3, v) / denom
  116. -> x3 = dot(-m2, v) / denom
  117. -> where u = cross(m2, m3)
  118. -> where v = cross(m1, d)
  119. -> where denom = dot(m1, u)
  120. Alternative Approach:
  121. -> Use X = ( d1 * cross(n2, n3) + d2 * cross(n3, n1) + d3 * cross(n1, n2) / dot(n1, cross(n2, n3)) )
  122. -> Derived by noticing that X = linear combination of the directions of the lines of intersection of the planes.
  123. -> with scalars a, b, c
  124. -> Insert these as point in each of three plane equations, simplifying and solving for "a", "b", "c"
  125. -> Then plugging a, b, c back into original expression of X as linear combo
  126. -> And simplifying.
  127. */
  128. return false;
  129. }
  130. bool BasicPrimitiveTests::IntersectLineAgainstLine(const Line & line_a, const Line & line_b, float & rtn_s, float & rtn_t)
  131. {
  132. ClosestPointOfTwoLines(line_a, line_b, rtn_s, rtn_t);
  133. Eigen::Vector3f point_a, point_b;
  134. line_a.GetPointAt(rtn_s, point_a);
  135. line_b.GetPointAt(rtn_t, point_b);
  136. return ((point_a - point_b).squaredNorm() < 1e-12);
  137. }
  138. bool BasicPrimitiveTests::IntersectLineAgainstSegment(const Line & line_a, const LineSegment & segment, float & rtn_s, float & rtn_t)
  139. {
  140. float rtn_value = IntersectLineAgainstLine(line_a, Line(segment.GetPointA(), segment.GetPointB() - segment.GetPointA()), rtn_s, rtn_t);
  141. return rtn_value && Between0And1(rtn_t);
  142. }