GteConvertCoordinates.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/GteMatrix.h>
12 
13 // Convert points and transformations between two coordinate systems.
14 // The mathematics involves a change of basis. See the document
15 // http://www.geometrictools.com/Documentation/ConvertingBetweenCoordinateSystems.pdf
16 // for the details. Typical usage for 3D conversion is shown next.
17 //
18 // // Linear change of basis.
19 // ConvertCoordinates<3, double> convert;
20 // Vector<3, double> X, Y, P0, P1, diff;
21 // Matrix<3, 3, double> U, V, A, B;
22 // bool isRHU, isRHV;
23 // U.SetCol(0, Vector3<double>{1.0, 0.0, 0.0});
24 // U.SetCol(1, Vector3<double>{0.0, 1.0, 0.0});
25 // U.SetCol(2, Vector3<double>{0.0, 0.0, 1.0});
26 // V.SetCol(0, Vector3<double>{1.0, 0.0, 0.0});
27 // V.SetCol(1, Vector3<double>{0.0, 0.0, 1.0});
28 // V.SetCol(2, Vector3<double>{0.0, 1.0, 0.0});
29 // convert(U, true, V, true);
30 // isRHU = convert.IsRightHandedU(); // true
31 // isRHV = convert.IsRightHandedV(); // false
32 // X = { 1.0, 2.0, 3.0 };
33 // Y = convert.UToV(X); // { 1.0, 3.0, 2.0 }
34 // P0 = U*X;
35 // P1 = V*Y;
36 // diff = P0 - P1; // { 0, 0, 0 }
37 // Y = { 0.0, 1.0, 2.0 };
38 // X = convert.VToU(Y); // { 0.0, 2.0, 1.0 }
39 // P0 = U*X;
40 // P1 = V*Y;
41 // diff = P0 - P1; // { 0, 0, 0 }
42 // double cs = 0.6, sn = 0.8; // cs*cs + sn*sn = 1
43 // A.SetCol(0, Vector3<double>{ c, s, 0.0});
44 // A.SetCol(1, Vector3<double>{ -s, c, 0.0});
45 // A.SetCol(2, Vector3<double>{0.0, 0.0, 1.0});
46 // B = convert.UToV(A);
47 // // B.GetCol(0) = { c, 0, s}
48 // // B.GetCol(1) = { 0, 1, 0}
49 // // B.GetCol(2) = {-s, 0, c}
50 // X = A*X; // U is VOR
51 // Y = B*Y; // V is VOR
52 // P0 = U*X;
53 // P1 = V*Y;
54 // diff = P0 - P1; // { 0, 0, 0 }
55 //
56 // // Affine change of basis.
57 // ConvertCoordinates<4, double> convert;
58 // Vector<4, double> X, Y, P0, P1, diff;
59 // Matrix<4, 4, double> U, V, A, B;
60 // bool isRHU, isRHV;
61 // U.SetCol(0, Vector4<double>{-1.0, 0.0, 0.0, 0.0});
62 // U.SetCol(1, Vector4<double>{0.0, 0.0, 1.0, 0.0});
63 // U.SetCol(2, Vector4<double>{0.0, -1.0, 0.0, 0.0});
64 // U.SetCol(3, Vector4<double>{1.0, 2.0, 3.0, 1.0});
65 // V.SetCol(0, Vector4<double>{0.0, 1.0, 0.0, 0.0});
66 // V.SetCol(1, Vector4<double>{-1.0, 0.0, 0.0, 0.0});
67 // V.SetCol(2, Vector4<double>{0.0, 0.0, 1.0, 0.0});
68 // V.SetCol(3, Vector4<double>{4.0, 5.0, 6.0, 1.0});
69 // convert(U, true, V, false);
70 // isRHU = convert.IsRightHandedU(); // false
71 // isRHV = convert.IsRightHandedV(); // true
72 // X = { -1.0, 4.0, -3.0, 1.0 };
73 // Y = convert.UToV(X); // { 0.0, 2.0, 1.0, 1.0 }
74 // P0 = U*X;
75 // P1 = V*Y;
76 // diff = P0 - P1; // { 0, 0, 0, 0 }
77 // Y = { 1.0, 2.0, 3.0, 1.0 };
78 // X = convert.VToU(Y); // { -1.0, 6.0, -4.0, 1.0 }
79 // P0 = U*X;
80 // P1 = V*Y;
81 // diff = P0 - P1; // { 0, 0, 0, 0 }
82 // double c = 0.6, s = 0.8; // c*c + s*s = 1
83 // A.SetCol(0, Vector4<double>{ c, s, 0.0, 0.0});
84 // A.SetCol(1, Vector4<double>{ -s, c, 0.0, 0.0});
85 // A.SetCol(2, Vector4<double>{0.0, 0.0, 1.0, 0.0});
86 // A.SetCol(3, Vector4<double>{0.3, 1.0, -2.0, 1.0});
87 // B = convert.UToV(A);
88 // // B.GetCol(0) = { 1, 0, 0, 0 }
89 // // B.GetCol(1) = { 0, c, s, 0 }
90 // // B.GetCol(2) = { 0, -s, c, 0 }
91 // // B.GetCol(3) = { 2.0, -0.9, -2.6, 1 }
92 // X = A*X; // U is VOR
93 // Y = Y*B; // V is VOL (not VOR)
94 // P0 = U*X;
95 // P1 = V*Y;
96 // diff = P0 - P1; // { 0, 0, 0, 0 }
97 
98 namespace gte
99 {
100 
101 template <int N, typename Real>
103 {
104 public:
105  // Construction of the change of basis matrix. The implementation
106  // supports both linear change of basis and affine change of basis.
108 
109  // Compute a change of basis between two coordinate systems. The return
110  // value is 'true' iff U and V are invertible. The matrix-vector
111  // multiplication conventions affect the conversion of matrix
112  // transformations. The Boolean inputs indicate how you want the matrices
113  // to be interpreted when applied as transformations of a vector.
114  bool operator()(
115  Matrix<N, N, Real> const& U, bool vectorOnRightU,
116  Matrix<N, N, Real> const& V, bool vectorOnRightV);
117 
118  // Member access.
119  inline Matrix<N, N, Real> const& GetC() const;
120  inline Matrix<N, N, Real> const& GetInverseC() const;
121  inline bool IsVectorOnRightU() const;
122  inline bool IsVectorOnRightV() const;
123  inline bool IsRightHandedU() const;
124  inline bool IsRightHandedV() const;
125 
126  // Convert points between coordinate systems. The names of the systems
127  // are U and V to make it clear which inputs of operator() they are
128  // associated with. The X vector stores coordinates for the U-system and
129  // the Y vector stores coordinates for the V-system.
130 
131  // Y = C^{-1}*X
132  inline Vector<N, Real> UToV(Vector<N, Real> const& X) const;
133 
134  // X = C*Y
135  inline Vector<N, Real> VToU(Vector<N, Real> const& Y) const;
136 
137  // Convert transformations between coordinate systems. The outputs are
138  // computed according to the tables shown before the function
139  // declarations. The superscript T denotes the transpose operator.
140  // vectorOnRightU = true: transformation is X' = A*X
141  // vectorOnRightU = false: transformation is (X')^T = X^T*A
142  // vectorOnRightV = true: transformation is Y' = B*Y
143  // vectorOnRightV = false: transformation is (Y')^T = Y^T*B
144 
145  // vectorOnRightU | vectorOnRightV | output
146  // ----------------+-----------------+---------------------
147  // true | true | C^{-1} * A * C
148  // true | false | (C^{-1} * A * C)^T
149  // false | true | C^{-1} * A^T * C
150  // false | false | (C^{-1} * A^T * C)^T
152 
153  // vectorOnRightU | vectorOnRightV | output
154  // ----------------+-----------------+---------------------
155  // true | true | C * B * C^{-1}
156  // true | false | C * B^T * C^{-1}
157  // false | true | (C * B * C^{-1})^T
158  // false | false | (C * B^T * C^{-1})^T
160 
161 private:
162  // C = U^{-1}*V, C^{-1} = V^{-1}*U
166 };
167 
168 
169 template <int N, typename Real>
171  :
172  mIsVectorOnRightU(true),
173  mIsVectorOnRightV(true),
174  mIsRightHandedU(true),
175  mIsRightHandedV(true)
176 {
177  mC.MakeIdentity();
179 }
180 
181 template <int N, typename Real>
183  Matrix<N, N, Real> const& U, bool vectorOnRightU,
184  Matrix<N, N, Real> const& V, bool vectorOnRightV)
185 {
186  // Initialize in case of early exit.
187  mC.MakeIdentity();
189  mIsVectorOnRightU = true;
190  mIsVectorOnRightV = true;
191  mIsRightHandedU = true;
192  mIsRightHandedV = true;
193 
194  Matrix<N, N, Real> inverseU;
195  Real determinantU;
196  bool invertibleU = GaussianElimination<Real>()(N, &U[0], &inverseU[0],
197  determinantU, nullptr, nullptr, nullptr, 0, nullptr);
198  if (!invertibleU)
199  {
200  return false;
201  }
202 
203  Matrix<N, N, Real> inverseV;
204  Real determinantV;
205  bool invertibleV = GaussianElimination<Real>()(N, &V[0], &inverseV[0],
206  determinantV, nullptr, nullptr, nullptr, 0, nullptr);
207  if (!invertibleV)
208  {
209  return false;
210  }
211 
212  mC = inverseU * V;
213  mInverseC = inverseV * U;
214  mIsVectorOnRightU = vectorOnRightU;
215  mIsVectorOnRightV = vectorOnRightV;
216  mIsRightHandedU = (determinantU > (Real)0);
217  mIsRightHandedV = (determinantV > (Real)0);
218  return true;
219 }
220 
221 template <int N, typename Real> inline
223 {
224  return mC;
225 }
226 
227 template <int N, typename Real> inline
229 {
230  return mInverseC;
231 }
232 
233 template <int N, typename Real> inline
235 {
236  return mIsVectorOnRightU;
237 }
238 
239 template <int N, typename Real> inline
241 {
242  return mIsVectorOnRightV;
243 }
244 
245 template <int N, typename Real> inline
247 {
248  return mIsRightHandedU;
249 }
250 
251 template <int N, typename Real> inline
253 {
254  return mIsRightHandedV;
255 }
256 
257 template <int N, typename Real> inline
259  const
260 {
261  return mInverseC * X;
262 }
263 
264 template <int N, typename Real> inline
266  const
267 {
268  return mC * Y;
269 }
270 
271 template <int N, typename Real>
273  Matrix<N, N, Real> const& A) const
274 {
275  Matrix<N, N, Real> product;
276 
277  if (mIsVectorOnRightU)
278  {
279  product = mInverseC * A * mC;
280  if (mIsVectorOnRightV)
281  {
282  return product;
283  }
284  else
285  {
286  return Transpose(product);
287  }
288  }
289  else
290  {
291  product = mInverseC * MultiplyATB(A, mC);
292  if (mIsVectorOnRightV)
293  {
294  return product;
295  }
296  else
297  {
298  return Transpose(product);
299  }
300  }
301 }
302 
303 template <int N, typename Real>
305  Matrix<N, N, Real> const& B) const
306 {
307  // vectorOnRightU | vectorOnRightV | output
308  // ----------------+-----------------+---------------------
309  // true | true | C * B * C^{-1}
310  // true | false | C * B^T * C^{-1}
311  // false | true | (C * B * C^{-1})^T
312  // false | false | (C * B^T * C^{-1})^T
313  Matrix<N, N, Real> product;
314 
315  if (mIsVectorOnRightV)
316  {
317  product = mC * B * mInverseC;
318  if (mIsVectorOnRightU)
319  {
320  return product;
321  }
322  else
323  {
324  return Transpose(product);
325  }
326  }
327  else
328  {
329  product = mC * MultiplyATB(B, mInverseC);
330  if (mIsVectorOnRightU)
331  {
332  return product;
333  }
334  else
335  {
336  return Transpose(product);
337  }
338  }
339 }
340 
341 
342 }
Vector< N, Real > UToV(Vector< N, Real > const &X) const
void MakeIdentity()
Definition: GteMatrix.h:462
Vector< N, Real > VToU(Vector< N, Real > const &Y) const
bool operator()(Matrix< N, N, Real > const &U, bool vectorOnRightU, Matrix< N, N, Real > const &V, bool vectorOnRightV)
GMatrix< Real > MultiplyATB(GMatrix< Real > const &A, GMatrix< Real > const &B)
Definition: GteGMatrix.h:737
GMatrix< Real > Transpose(GMatrix< Real > const &M)
Definition: GteGMatrix.h:637
Matrix< N, N, Real > mInverseC
Matrix< N, N, Real > const & GetC() const
Matrix< N, N, Real > const & GetInverseC() const


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 03:59:59