#### /src/Geometry_GeometricTests/BPT_AdditionalTests.cpp

C++ | 163 lines | 35 code | 5 blank | 123 comment | 1 complexity | c6a447188114f63c614bdd1a8759f1c5 MD5 | raw file

Possible License(s): AGPL-3.0, LGPL-2.1, LGPL-3.0, GPL-2.0

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