GteVector2.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.1 (2016/07/08)
7 
8 #pragma once
9 
10 #include <Mathematics/GteVector.h>
11 
12 namespace gte
13 {
14 
15 // Template alias for convenience.
16 template <typename Real>
18 
19 // Compute the perpendicular using the formal determinant,
20 // perp = det{{e0,e1},{x0,x1}} = (x1,-x0)
21 // where e0 = (1,0), e1 = (0,1), and v = (x0,x1).
22 template <typename Real>
24 
25 // Compute the normalized perpendicular.
26 template <typename Real>
27 Vector2<Real> UnitPerp(Vector2<Real> const& v, bool robust = false);
28 
29 // Compute Dot((x0,x1),Perp(y0,y1)) = x0*y1 - x1*y0, where v0 = (x0,x1)
30 // and v1 = (y0,y1).
31 template <typename Real>
32 Real DotPerp(Vector2<Real> const& v0, Vector2<Real> const& v1);
33 
34 // Compute a right-handed orthonormal basis for the orthogonal complement
35 // of the input vectors. The function returns the smallest length of the
36 // unnormalized vectors computed during the process. If this value is nearly
37 // zero, it is possible that the inputs are linearly dependent (within
38 // numerical round-off errors). On input, numInputs must be 1 and v[0]
39 // must be initialized. On output, the vectors v[0] and v[1] form an
40 // orthonormal set.
41 template <typename Real>
42 Real ComputeOrthogonalComplement(int numInputs, Vector2<Real>* v, bool robust = false);
43 
44 // Compute the barycentric coordinates of the point P with respect to the
45 // triangle <V0,V1,V2>, P = b0*V0 + b1*V1 + b2*V2, where b0 + b1 + b2 = 1.
46 // The return value is 'true' iff {V0,V1,V2} is a linearly independent set.
47 // Numerically, this is measured by |det[V0 V1 V2]| <= epsilon. The values
48 // bary[] are valid only when the return value is 'true' but set to zero when
49 // the return value is 'false'.
50 template <typename Real>
52  Vector2<Real> const& v1, Vector2<Real> const& v2, Real bary[3],
53  Real epsilon = (Real)0);
54 
55 // Get intrinsic information about the input array of vectors. The return
56 // value is 'true' iff the inputs are valid (numVectors > 0, v is not null,
57 // and epsilon >= 0), in which case the class members are valid.
58 template <typename Real>
60 {
61 public:
62  // The constructor sets the class members based on the input set.
63  IntrinsicsVector2(int numVectors, Vector2<Real> const* v, Real inEpsilon);
64 
65  // A nonnegative tolerance that is used to determine the intrinsic
66  // dimension of the set.
67  Real epsilon;
68 
69  // The intrinsic dimension of the input set, computed based on the
70  // nonnegative tolerance mEpsilon.
71  int dimension;
72 
73  // Axis-aligned bounding box of the input set. The maximum range is
74  // the larger of max[0]-min[0] and max[1]-min[1].
75  Real min[2], max[2];
76  Real maxRange;
77 
78  // Coordinate system. The origin is valid for any dimension d. The
79  // unit-length direction vector is valid only for 0 <= i < d. The
80  // extreme index is relative to the array of input points, and is also
81  // valid only for 0 <= i < d. If d = 0, all points are effectively
82  // the same, but the use of an epsilon may lead to an extreme index
83  // that is not zero. If d = 1, all points effectively lie on a line
84  // segment. If d = 2, the points are not collinear.
87 
88  // The indices that define the maximum dimensional extents. The
89  // values extreme[0] and extreme[1] are the indices for the points
90  // that define the largest extent in one of the coordinate axis
91  // directions. If the dimension is 2, then extreme[2] is the index
92  // for the point that generates the largest extent in the direction
93  // perpendicular to the line through the points corresponding to
94  // extreme[0] and extreme[1]. The triangle formed by the points
95  // V[extreme[0]], V[extreme[1]], and V[extreme[2]] is clockwise or
96  // counterclockwise, the condition stored in extremeCCW.
97  int extreme[3];
98  bool extremeCCW;
99 };
100 
101 
102 template <typename Real>
104 {
105  return Vector2<Real>{ v[1], -v[0] };
106 }
107 
108 template <typename Real>
109 Vector2<Real> UnitPerp(Vector2<Real> const& v, bool robust)
110 {
111  Vector2<Real> unitPerp{ v[1], -v[0] };
112  Normalize(unitPerp, robust);
113  return unitPerp;
114 }
115 
116 template <typename Real>
117 Real DotPerp(Vector2<Real> const& v0, Vector2<Real> const& v1)
118 {
119  return Dot(v0, Perp(v1));
120 }
121 
122 template <typename Real>
123 Real ComputeOrthogonalComplement(int numInputs, Vector2<Real>* v, bool robust)
124 {
125  if (numInputs == 1)
126  {
127  v[1] = -Perp(v[0]);
128  return Orthonormalize<2, Real>(2, v, robust);
129  }
130 
131  return (Real)0;
132 }
133 
134 template <typename Real>
136  Vector2<Real> const& v1, Vector2<Real> const& v2, Real bary[3],
137  Real epsilon)
138 {
139  // Compute the vectors relative to V2 of the triangle.
140  Vector2<Real> diff[3] = { v0 - v2, v1 - v2, p - v2 };
141 
142  Real det = DotPerp(diff[0], diff[1]);
143  if (det < -epsilon || det > epsilon)
144  {
145  Real invDet = ((Real)1) / det;
146  bary[0] = DotPerp(diff[2], diff[1])*invDet;
147  bary[1] = DotPerp(diff[0], diff[2])*invDet;
148  bary[2] = (Real)1 - bary[0] - bary[1];
149  return true;
150  }
151 
152  for (int i = 0; i < 3; ++i)
153  {
154  bary[i] = (Real)0;
155  }
156  return false;
157 }
158 
159 template <typename Real>
161  Vector2<Real> const* v, Real inEpsilon)
162  :
163  epsilon(inEpsilon),
164  dimension(0),
165  maxRange((Real)0),
166  origin({ (Real)0, (Real)0 }),
167  extremeCCW(false)
168 {
169  min[0] = (Real)0;
170  min[1] = (Real)0;
171  direction[0] = { (Real)0, (Real)0 };
172  direction[1] = { (Real)0, (Real)0 };
173  extreme[0] = 0;
174  extreme[1] = 0;
175  extreme[2] = 0;
176 
177  if (numVectors > 0 && v && epsilon >= (Real)0)
178  {
179  // Compute the axis-aligned bounding box for the input vectors. Keep
180  // track of the indices into 'vectors' for the current min and max.
181  int j, indexMin[2], indexMax[2];
182  for (j = 0; j < 2; ++j)
183  {
184  min[j] = v[0][j];
185  max[j] = min[j];
186  indexMin[j] = 0;
187  indexMax[j] = 0;
188  }
189 
190  int i;
191  for (i = 1; i < numVectors; ++i)
192  {
193  for (j = 0; j < 2; ++j)
194  {
195  if (v[i][j] < min[j])
196  {
197  min[j] = v[i][j];
198  indexMin[j] = i;
199  }
200  else if (v[i][j] > max[j])
201  {
202  max[j] = v[i][j];
203  indexMax[j] = i;
204  }
205  }
206  }
207 
208  // Determine the maximum range for the bounding box.
209  maxRange = max[0] - min[0];
210  extreme[0] = indexMin[0];
211  extreme[1] = indexMax[0];
212  Real range = max[1] - min[1];
213  if (range > maxRange)
214  {
215  maxRange = range;
216  extreme[0] = indexMin[1];
217  extreme[1] = indexMax[1];
218  }
219 
220  // The origin is either the vector of minimum x0-value or vector of
221  // minimum x1-value.
222  origin = v[extreme[0]];
223 
224  // Test whether the vector set is (nearly) a vector.
225  if (maxRange <= epsilon)
226  {
227  dimension = 0;
228  for (j = 0; j < 2; ++j)
229  {
230  extreme[j + 1] = extreme[0];
231  }
232  return;
233  }
234 
235  // Test whether the vector set is (nearly) a line segment. We need
236  // direction[1] to span the orthogonal complement of direction[0].
237  direction[0] = v[extreme[1]] - origin;
238  Normalize(direction[0], false);
239  direction[1] = -Perp(direction[0]);
240 
241  // Compute the maximum distance of the points from the line
242  // origin+t*direction[0].
243  Real maxDistance = (Real)0;
244  Real maxSign = (Real)0;
245  extreme[2] = extreme[0];
246  for (i = 0; i < numVectors; ++i)
247  {
248  Vector2<Real> diff = v[i] - origin;
249  Real distance = Dot(direction[1], diff);
250  Real sign = (distance >(Real)0 ? (Real)1 :
251  (distance < (Real)0 ? (Real)-1 : (Real)0));
252  distance = fabs(distance);
253  if (distance > maxDistance)
254  {
255  maxDistance = distance;
256  maxSign = sign;
257  extreme[2] = i;
258  }
259  }
260 
261  if (maxDistance <= epsilon * maxRange)
262  {
263  // The points are (nearly) on the line origin+t*direction[0].
264  dimension = 1;
265  extreme[2] = extreme[1];
266  return;
267  }
268 
269  dimension = 2;
270  extremeCCW = (maxSign > (Real)0);
271  return;
272  }
273 }
274 
275 
276 }
Vector2< Real > UnitPerp(Vector2< Real > const &v, bool robust=false)
Definition: GteVector2.h:109
Vector2< Real > origin
Definition: GteVector2.h:85
GLfloat GLfloat v1
Definition: glcorearb.h:812
GLsizei GLsizei GLfloat distance
Definition: glext.h:9704
Real DotPerp(Vector2< Real > const &v0, Vector2< Real > const &v1)
Definition: GteVector2.h:117
DualQuaternion< Real > Dot(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
Real Normalize(GVector< Real > &v, bool robust=false)
Definition: GteGVector.h:454
GLfloat v0
Definition: glcorearb.h:811
Vector2< Real > Perp(Vector2< Real > const &v)
Definition: GteVector2.h:103
bool ComputeBarycentrics(Vector2< Real > const &p, Vector2< Real > const &v0, Vector2< Real > const &v1, Vector2< Real > const &v2, Real bary[3], Real epsilon=(Real) 0)
Definition: GteVector2.h:135
const GLdouble * v
Definition: glcorearb.h:832
GLfloat GLfloat GLfloat v2
Definition: glcorearb.h:813
GLenum GLint * range
Definition: glcorearb.h:1920
Real ComputeOrthogonalComplement(int numInputs, Vector2< Real > *v, bool robust=false)
Definition: GteVector2.h:123
IntrinsicsVector2(int numVectors, Vector2< Real > const *v, Real inEpsilon)
Definition: GteVector2.h:160
GLfloat GLfloat p
Definition: glext.h:11668
Vector2< Real > direction[2]
Definition: GteVector2.h:86


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