PageRenderTime 15ms CodeModel.GetById 1ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/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
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}