http://github.com/Akranar/daguerreo
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}
```