GteVector4.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/GteVector3.h>
11 
12 namespace gte
13 {
14 
15 // Template alias for convenience.
16 template <typename Real>
18 
19 // In GteVector3.h, the Vector3 Cross, UnitCross, and DotCross have a template
20 // parameter N that should be 3 or 4. The latter case supports affine vectors
21 // in 4D (last component w = 0) when you want to use 4-tuples and 4x4 matrices
22 // for affine algebra. Thus, you may use those template functions for Vector4.
23 
24 // Compute the hypercross product using the formal determinant:
25 // hcross = det{{e0,e1,e2,e3},{x0,x1,x2,x3},{y0,y1,y2,y3},{z0,z1,z2,z3}}
26 // where e0 = (1,0,0,0), e1 = (0,1,0,0), e2 = (0,0,1,0), e3 = (0,0,0,1),
27 // v0 = (x0,x1,x2,x3), v1 = (y0,y1,y2,y3), and v2 = (z0,z1,z2,z3).
28 template <typename Real>
30  Vector4<Real> const& v2);
31 
32 // Compute the normalized hypercross product.
33 template <typename Real>
35  Vector4<Real> const& v1, Vector4<Real> const& v2, bool robust = false);
36 
37 // Compute Dot(HyperCross((x0,x1,x2,x3),(y0,y1,y2,y3),(z0,z1,z2,z3)),
38 // (w0,w1,w2,w3)), where v0 = (x0,x1,x2,x3), v1 = (y0,y1,y2,y3),
39 // v2 = (z0,z1,z2,z3), and v3 = (w0,w1,w2,w3).
40 template <typename Real>
41 Real DotHyperCross(Vector4<Real> const& v0, Vector4<Real> const& v1,
42  Vector4<Real> const& v2, Vector4<Real> const& v3);
43 
44 // Compute a right-handed orthonormal basis for the orthogonal complement
45 // of the input vectors. The function returns the smallest length of the
46 // unnormalized vectors computed during the process. If this value is nearly
47 // zero, it is possible that the inputs are linearly dependent (within
48 // numerical round-off errors). On input, numInputs must be 1, 2, or 3 and
49 // v[0] through v[numInputs-1] must be initialized. On output, the vectors
50 // v[0] through v[3] form an orthonormal set.
51 template <typename Real>
52 Real ComputeOrthogonalComplement(int numInputs, Vector4<Real>* v,
53  bool robust = false);
54 
55 
56 template <typename Real>
58  Vector4<Real> const& v2)
59 {
60  Real m01 = v0[0] * v1[1] - v0[1] * v1[0]; // x0*y1 - y0*x1
61  Real m02 = v0[0] * v1[2] - v0[2] * v1[0]; // x0*z1 - z0*x1
62  Real m03 = v0[0] * v1[3] - v0[3] * v1[0]; // x0*w1 - w0*x1
63  Real m12 = v0[1] * v1[2] - v0[2] * v1[1]; // y0*z1 - z0*y1
64  Real m13 = v0[1] * v1[3] - v0[3] * v1[1]; // y0*w1 - w0*y1
65  Real m23 = v0[2] * v1[3] - v0[3] * v1[2]; // z0*w1 - w0*z1
66  return Vector4<Real>
67  {
68  +m23*v2[1] - m13*v2[2] + m12*v2[3], // +m23*y2 - m13*z2 + m12*w2
69  -m23*v2[0] + m03*v2[2] - m02*v2[3], // -m23*x2 + m03*z2 - m02*w2
70  +m13*v2[0] - m03*v2[1] + m01*v2[3], // +m13*x2 - m03*y2 + m01*w2
71  -m12*v2[0] + m02*v2[1] - m01*v2[2] // -m12*x2 + m02*y2 - m01*z2
72  };
73 }
74 
75 template <typename Real>
77  Vector4<Real> const& v1, Vector4<Real> const& v2, bool robust)
78 {
79  Vector4<Real> unitHyperCross = HyperCross(v0, v1, v2);
80  Normalize(unitHyperCross, robust);
81  return unitHyperCross;
82 }
83 
84 template <typename Real>
86  Vector4<Real> const& v2, Vector4<Real> const& v3)
87 {
88  return Dot(HyperCross(v0, v1, v2), v3);
89 }
90 
91 template <typename Real>
92 Real ComputeOrthogonalComplement(int numInputs, Vector4<Real>* v, bool robust)
93 {
94  if (numInputs == 1)
95  {
96  int maxIndex = 0;
97  Real maxAbsValue = fabs(v[0][0]);
98  for (int i = 1; i < 4; ++i)
99  {
100  Real absValue = fabs(v[0][i]);
101  if (absValue > maxAbsValue)
102  {
103  maxIndex = i;
104  maxAbsValue = absValue;
105  }
106  }
107 
108  if (maxIndex < 2)
109  {
110  v[1][0] = -v[0][1];
111  v[1][1] = +v[0][0];
112  v[1][2] = (Real)0;
113  v[1][3] = (Real)0;
114  }
115  else if (maxIndex == 3)
116  {
117  // Generally, you can skip this clause and swap the last two
118  // components. However, by swapping 2 and 3 in this case, we
119  // allow the function to work properly when the inputs are 3D
120  // vectors represented as 4D affine vectors (w = 0).
121  v[1][0] = (Real)0;
122  v[1][1] = +v[0][2];
123  v[1][2] = -v[0][1];
124  v[1][3] = (Real)0;
125  }
126  else
127  {
128  v[1][0] = (Real)0;
129  v[1][1] = (Real)0;
130  v[1][2] = -v[0][3];
131  v[1][3] = +v[0][2];
132  }
133 
134  numInputs = 2;
135  }
136 
137  if (numInputs == 2)
138  {
139  Real det[6] =
140  {
141  v[0][0] * v[1][1] - v[1][0] * v[0][1],
142  v[0][0] * v[1][2] - v[1][0] * v[0][2],
143  v[0][0] * v[1][3] - v[1][0] * v[0][3],
144  v[0][1] * v[1][2] - v[1][1] * v[0][2],
145  v[0][1] * v[1][3] - v[1][1] * v[0][3],
146  v[0][2] * v[1][3] - v[1][2] * v[0][3]
147  };
148 
149  int maxIndex = 0;
150  Real maxAbsValue = fabs(det[0]);
151  for (int i = 1; i < 6; ++i)
152  {
153  Real absValue = fabs(det[i]);
154  if (absValue > maxAbsValue)
155  {
156  maxIndex = i;
157  maxAbsValue = absValue;
158  }
159  }
160 
161  if (maxIndex == 0)
162  {
163  v[2] = { -det[4], +det[2], (Real)0, -det[0] };
164  }
165  else if (maxIndex <= 2)
166  {
167  v[2] = { +det[5], (Real)0, -det[2], +det[1] };
168  }
169  else
170  {
171  v[2] = { (Real)0, -det[5], +det[4], -det[3] };
172  }
173 
174  numInputs = 3;
175  }
176 
177  if (numInputs == 3)
178  {
179  v[3] = HyperCross(v[0], v[1], v[2]);
180  return Orthonormalize<4, Real>(4, v, robust);
181  }
182 
183  return (Real)0;
184 }
185 
186 }
GLfloat GLfloat v1
Definition: glcorearb.h:812
Vector4< Real > UnitHyperCross(Vector4< Real > const &v0, Vector4< Real > const &v1, Vector4< Real > const &v2, bool robust=false)
Definition: GteVector4.h:76
DualQuaternion< Real > Dot(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
GLfloat GLfloat GLfloat GLfloat v3
Definition: glcorearb.h:814
Real Normalize(GVector< Real > &v, bool robust=false)
Definition: GteGVector.h:454
GLfloat v0
Definition: glcorearb.h:811
const GLdouble * v
Definition: glcorearb.h:832
GLfloat GLfloat GLfloat v2
Definition: glcorearb.h:813
Real ComputeOrthogonalComplement(int numInputs, Vector2< Real > *v, bool robust=false)
Definition: GteVector2.h:123
Real DotHyperCross(Vector4< Real > const &v0, Vector4< Real > const &v1, Vector4< Real > const &v2, Vector4< Real > const &v3)
Definition: GteVector4.h:85
Vector4< Real > HyperCross(Vector4< Real > const &v0, Vector4< Real > const &v1, Vector4< Real > const &v2)
Definition: GteVector4.h:57


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