GteIntrPlane3Plane3.h
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.0 (2016/06/19)
7 
8 #pragma once
9 
10 #include <Mathematics/GteVector3.h>
12 #include <Mathematics/GteLine.h>
13 #include <Mathematics/GteFIQuery.h>
14 #include <Mathematics/GteTIQuery.h>
15 
16 namespace gte
17 {
18 
19 template <typename Real>
20 class TIQuery<Real, Plane3<Real>, Plane3<Real>>
21 {
22 public:
23  struct Result
24  {
25  bool intersect;
26  };
27 
28  Result operator()(Plane3<Real> const& plane0, Plane3<Real> const& plane1);
29 };
30 
31 template <typename Real>
32 class FIQuery<Real, Plane3<Real>, Plane3<Real>>
33 {
34 public:
35  struct Result
36  {
37  bool intersect;
38 
39  // If 'intersect' is true, the intersection is either a line or the
40  // planes are the same. When a line, 'line' is valid. When a plane,
41  // 'plane' is set to one of the planes.
42  bool isLine;
45  };
46 
47  Result operator()(Plane3<Real> const& plane0, Plane3<Real> const& plane1);
48 };
49 
50 
51 template <typename Real>
54  Plane3<Real> const& plane0, Plane3<Real> const& plane1)
55 {
56  // If Cross(N0,N1) is zero, then either planes are parallel and separated
57  // or the same plane. In both cases, 'false' is returned. Otherwise, the
58  // planes intersect. To avoid subtle differences in reporting between
59  // Test() and Find(), the same parallel test is used. Mathematically,
60  // |Cross(N0,N1)|^2 = Dot(N0,N0)*Dot(N1,N1)-Dot(N0,N1)^2
61  // = 1 - Dot(N0,N1)^2
62  // The last equality is true since planes are required to have unit-length
63  // normal vectors. The test |Cross(N0,N1)| = 0 is the same as
64  // |Dot(N0,N1)| = 1.
65 
66  Result result;
67  Real dot = Dot(plane0.normal, plane1.normal);
68  if (std::abs(dot) < (Real)1)
69  {
70  result.intersect = true;
71  return result;
72  }
73 
74  // The planes are parallel. Check whether they are coplanar.
75  Real cDiff;
76  if (dot >= (Real)0)
77  {
78  // Normals are in same direction, need to look at c0-c1.
79  cDiff = plane0.constant - plane1.constant;
80  }
81  else
82  {
83  // Normals are in opposite directions, need to look at c0+c1.
84  cDiff = plane0.constant + plane1.constant;
85  }
86 
87  result.intersect = (std::abs(cDiff) == (Real)0);
88  return result;
89 }
90 
91 
92 
93 template <typename Real>
96  Plane3<Real> const& plane0, Plane3<Real> const& plane1)
97 {
98  // If N0 and N1 are parallel, either the planes are parallel and separated
99  // or the same plane. In both cases, 'false' is returned. Otherwise,
100  // the intersection line is
101  // L(t) = t*Cross(N0,N1)/|Cross(N0,N1)| + c0*N0 + c1*N1
102  // for some coefficients c0 and c1 and for t any real number (the line
103  // parameter). Taking dot products with the normals,
104  // d0 = Dot(N0,L) = c0*Dot(N0,N0) + c1*Dot(N0,N1) = c0 + c1*d
105  // d1 = Dot(N1,L) = c0*Dot(N0,N1) + c1*Dot(N1,N1) = c0*d + c1
106  // where d = Dot(N0,N1). These are two equations in two unknowns. The
107  // solution is
108  // c0 = (d0 - d*d1)/det
109  // c1 = (d1 - d*d0)/det
110  // where det = 1 - d^2.
111 
112  Result result;
113 
114  Real dot = Dot(plane0.normal, plane1.normal);
115  if (std::abs(dot) >= (Real)1)
116  {
117  // The planes are parallel. Check if they are coplanar.
118  Real cDiff;
119  if (dot >= (Real)0)
120  {
121  // Normals are in same direction, need to look at c0-c1.
122  cDiff = plane0.constant - plane1.constant;
123  }
124  else
125  {
126  // Normals are in opposite directions, need to look at c0+c1.
127  cDiff = plane0.constant + plane1.constant;
128  }
129 
130  if (std::abs(cDiff) == (Real)0)
131  {
132  // The planes are coplanar.
133  result.intersect = true;
134  result.isLine = false;
135  result.plane = plane0;
136  return result;
137  }
138 
139  // The planes are parallel but distinct.
140  result.intersect = false;
141  return result;
142  }
143 
144  Real invDet = ((Real)1) / ((Real)1 - dot*dot);
145  Real c0 = (plane0.constant - dot*plane1.constant)*invDet;
146  Real c1 = (plane1.constant - dot*plane0.constant)*invDet;
147  result.intersect = true;
148  result.isLine = true;
149  result.line.origin = c0*plane0.normal + c1*plane1.normal;
150  result.line.direction = UnitCross(plane0.normal, plane1.normal);
151  return result;
152 }
153 
154 
155 }
gte::BSNumber< UIntegerType > abs(gte::BSNumber< UIntegerType > const &number)
Definition: GteBSNumber.h:966
Vector< N, Real > UnitCross(Vector< N, Real > const &v0, Vector< N, Real > const &v1, bool robust=false)
Definition: GteVector3.h:130
DualQuaternion< Real > Dot(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
Result operator()(Type0 const &primitive0, Type1 const &primitive1)
GLuint64EXT * result
Definition: glext.h:10003


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:00