GteIntrPlane3Circle3.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/GteCircle3.h>
12 
13 namespace gte
14 {
15 
16 template <typename Real>
17 class TIQuery<Real, Plane3<Real>, Circle3<Real>>
18 {
19 public:
20  struct Result
21  {
22  bool intersect;
23  };
24 
25  Result operator()(Plane3<Real> const& plane, Circle3<Real> const& circle);
26 };
27 
28 template <typename Real>
29 class FIQuery<Real, Plane3<Real>, Circle3<Real>>
30 {
31 public:
32  struct Result
33  {
34  bool intersect;
35 
36  // If 'intersect' is true, the intersection is either 1 or 2 points
37  // or the entire circle. When points, 'numIntersections' and
38  // 'point' are valid. When a circle, 'circle' is set to the incoming
39  // circle.
40  bool isPoints;
42  Vector3<Real> point[2];
44  };
45 
46  Result operator()(Plane3<Real> const& plane, Circle3<Real> const& circle);
47 };
48 
49 
50 template <typename Real>
53  Plane3<Real> const& plane, Circle3<Real> const& circle)
54 {
55  Result result;
56 
57  // Construct the plane of the circle.
58  Plane3<Real> cPlane(circle.normal, circle.center);
59 
60  // Compute the intersection of this plane with the input plane.
62  auto ppResult = ppQuery(plane, cPlane);
63  if (!ppResult.intersect)
64  {
65  // Planes are parallel and nonintersecting.
66  result.intersect = false;
67  return result;
68  }
69 
70  if (!ppResult.isLine)
71  {
72  // Planes are the same, the circle is the common intersection set.
73  result.intersect = true;
74  return result;
75  }
76 
77  // The planes intersect in a line. Locate one or two points that are on
78  // the circle and line. If the line is t*D+P, the circle center is C,
79  // and the circle radius is r, then
80  // r^2 = |t*D+P-C|^2 = |D|^2*t^2 + 2*Dot(D,P-C)*t + |P-C|^2
81  // This is a quadratic equation of the form a2*t^2 + 2*a1*t + a0 = 0.
82  Vector3<Real> diff = ppResult.line.origin - circle.center;
83  Real a2 = Dot(ppResult.line.direction, ppResult.line.direction);
84  Real a1 = Dot(diff, ppResult.line.direction);
85  Real a0 = Dot(diff, diff) - circle.radius*circle.radius;
86 
87  // Real-valued roots imply an intersection.
88  Real discr = a1*a1 - a0*a2;
89  result.intersect = (discr >= (Real)0);
90  return result;
91 }
92 
93 
94 
95 template <typename Real>
98  Plane3<Real> const& plane, Circle3<Real> const& circle)
99 {
100  Result result;
101 
102  // Construct the plane of the circle.
103  Plane3<Real> cPlane(circle.normal, circle.center);
104 
105  // Compute the intersection of this plane with the input plane.
107  auto ppResult = ppQuery(plane, cPlane);
108  if (!ppResult.intersect)
109  {
110  // Planes are parallel and nonintersecting.
111  result.intersect = false;
112  return result;
113  }
114 
115  if (!ppResult.isLine)
116  {
117  // Planes are the same, the circle is the common intersection set.
118  result.intersect = true;
119  result.isPoints = false;
120  result.circle = circle;
121  return result;
122  }
123 
124  // The planes intersect in a line. Locate one or two points that are on
125  // the circle and line. If the line is t*D+P, the circle center is C,
126  // and the circle radius is r, then
127  // r^2 = |t*D+P-C|^2 = |D|^2*t^2 + 2*Dot(D,P-C)*t + |P-C|^2
128  // This is a quadratic equation of the form a2*t^2 + 2*a1*t + a0 = 0.
129  Vector3<Real> diff = ppResult.line.origin - circle.center;
130  Real a2 = Dot(ppResult.line.direction, ppResult.line.direction);
131  Real a1 = Dot(diff, ppResult.line.direction);
132  Real a0 = Dot(diff, diff) - circle.radius*circle.radius;
133 
134  Real discr = a1*a1 - a0*a2;
135  if (discr < (Real)0)
136  {
137  // No real roots, the circle does not intersect the plane.
138  result.intersect = false;
139  return result;
140  }
141 
142  result.isPoints = true;
143 
144  Real inv = ((Real)1) / a2;
145  if (discr == (Real)0)
146  {
147  // One repeated root, the circle just touches the plane.
148  result.numIntersections = 1;
149  result.point[0] =
150  ppResult.line.origin - (a1*inv)*ppResult.line.direction;
151  return result;
152  }
153 
154  // Two distinct, real-valued roots, the circle intersects the plane in
155  // two points.
156  Real root = sqrt(discr);
157  result.numIntersections = 2;
158  result.point[0] =
159  ppResult.line.origin - ((a1 + root)*inv)*ppResult.line.direction;
160  result.point[1] =
161  ppResult.line.origin - ((a1 - root)*inv)*ppResult.line.direction;
162  return result;
163 }
164 
165 
166 }
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