GteIntrLine2Line2.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/GteVector2.h>
11 #include <Mathematics/GteLine.h>
12 #include <Mathematics/GteFIQuery.h>
13 #include <Mathematics/GteTIQuery.h>
14 #include <limits>
15 
16 namespace gte
17 {
18 
19 template <typename Real>
20 class TIQuery<Real, Line2<Real>, Line2<Real>>
21 {
22 public:
23  struct Result
24  {
25  bool intersect;
26 
27  // The number is 0 (no intersection), 1 (lines intersect in a single
28  // point) or std::numeric_limits<int>::max() (lines are the same).
30  };
31 
32  Result operator()(Line2<Real> const& line0, Line2<Real> const& line1);
33 };
34 
35 template <typename Real>
36 class FIQuery<Real, Line2<Real>, Line2<Real>>
37 {
38 public:
39  struct Result
40  {
41  bool intersect;
42 
43  // The number is 0 (no intersection), 1 (lines intersect in a single
44  // point) or std::numeric_limits<int>::max() (lines are the same).
46 
47  // If numIntersections is 1, the intersection is
48  // point = line0.origin + line0parameter[0] * line0.direction
49  // = line1.origin + line1parameter[0] * line1.direction
50  // If numIntersections is maxInt, point is not valid but the
51  // intervals are
52  // line0Parameter[] = { -maxReal, +maxReal }
53  // line1Parameter[] = { -maxReal, +maxReal }
54  Real line0Parameter[2], line1Parameter[2];
56  };
57 
58  Result operator()(Line2<Real> const& line0, Line2<Real> const& line1);
59 };
60 
61 
62 template <typename Real>
63 typename TIQuery<Real, Line2<Real>, Line2<Real>>::Result
65  Line2<Real> const& line0, Line2<Real> const& line1)
66 {
67  Result result;
68 
69  // The intersection of two lines is a solution to P0 + s0*D0 = P1 + s1*D1.
70  // Rewrite this as s0*D0 - s1*D1 = P1 - P0 = Q. If DotPerp(D0, D1)) = 0,
71  // the lines are parallel. Additionally, if DotPerp(Q, D1)) = 0, the
72  // lines are the same. If Dotperp(D0, D1)) is not zero, then
73  // s0 = DotPerp(Q, D1))/DotPerp(D0, D1))
74  // produces the point of intersection. Also,
75  // s1 = DotPerp(Q, D0))/DotPerp(D0, D1))
76 
77  Vector2<Real> diff = line1.origin - line0.origin;
78  Real D0DotPerpD1 = DotPerp(line0.direction, line1.direction);
79  if (D0DotPerpD1 != (Real)0)
80  {
81  // The lines are not parallel.
82  result.intersect = true;
83  result.numIntersections = 1;
84  }
85  else
86  {
87  // The lines are parallel.
88  Normalize(diff);
89  Real diffNDotPerpD1 = DotPerp(diff, line1.direction);
90  if (diffNDotPerpD1 != (Real)0)
91  {
92  // The lines are parallel but distinct.
93  result.intersect = false;
94  result.numIntersections = 0;
95  }
96  else
97  {
98  // The lines are the same.
99  result.intersect = true;
100  result.numIntersections = std::numeric_limits<int>::max();
101  }
102  }
103 
104  return result;
105 }
106 
107 template <typename Real>
108 typename FIQuery<Real, Line2<Real>, Line2<Real>>::Result
110  Line2<Real> const& line0, Line2<Real> const& line1)
111 {
112  Result result;
113 
114  // The intersection of two lines is a solution to P0 + s0*D0 = P1 + s1*D1.
115  // Rewrite this as s0*D0 - s1*D1 = P1 - P0 = Q. If DotPerp(D0, D1)) = 0,
116  // the lines are parallel. Additionally, if DotPerp(Q, D1)) = 0, the
117  // lines are the same. If Dotperp(D0, D1)) is not zero, then
118  // s0 = DotPerp(Q, D1))/DotPerp(D0, D1))
119  // produces the point of intersection. Also,
120  // s1 = DotPerp(Q, D0))/DotPerp(D0, D1))
121 
122  Vector2<Real> diff = line1.origin - line0.origin;
123  Real D0DotPerpD1 = DotPerp(line0.direction, line1.direction);
124  if (D0DotPerpD1 != (Real)0)
125  {
126  // The lines are not parallel.
127  result.intersect = true;
128  result.numIntersections = 1;
129  Real invD0DotPerpD1 = ((Real)1) / D0DotPerpD1;
130  Real diffDotPerpD0 = DotPerp(diff, line0.direction);
131  Real diffDotPerpD1 = DotPerp(diff, line1.direction);
132  Real s0 = diffDotPerpD1*invD0DotPerpD1;
133  Real s1 = diffDotPerpD0*invD0DotPerpD1;
134  result.line0Parameter[0] = s0;
135  result.line1Parameter[0] = s1;
136  result.point = line0.origin + s0 * line0.direction;
137  }
138  else
139  {
140  // The lines are parallel.
141  Normalize(diff);
142  Real diffNDotPerpD1 = DotPerp(diff, line1.direction);
143  if (std::abs(diffNDotPerpD1) != (Real)0)
144  {
145  // The lines are parallel but distinct.
146  result.intersect = false;
147  result.numIntersections = 0;
148  }
149  else
150  {
151  // The lines are the same.
152  result.intersect = true;
153  result.numIntersections = std::numeric_limits<int>::max();
154  Real maxReal = std::numeric_limits<Real>::max();
155  result.line0Parameter[0] = -maxReal;
156  result.line0Parameter[1] = +maxReal;
157  result.line1Parameter[0] = -maxReal;
158  result.line1Parameter[1] = +maxReal;
159  }
160  }
161 
162  return result;
163 }
164 
165 
166 }
gte::BSNumber< UIntegerType > abs(gte::BSNumber< UIntegerType > const &number)
Definition: GteBSNumber.h:966
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s0
Definition: glext.h:9013
Real DotPerp(Vector2< Real > const &v0, Vector2< Real > const &v1)
Definition: GteVector2.h:117
Real Normalize(GVector< Real > &v, bool robust=false)
Definition: GteGVector.h:454
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
Definition: glext.h:9013
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