Simbody  3.5
UnitVec.h
Go to the documentation of this file.
1 #ifndef SimTK_UNITVEC_H
2 #define SimTK_UNITVEC_H
3 
4 /* -------------------------------------------------------------------------- *
5  * Simbody(tm): SimTKcommon *
6  * -------------------------------------------------------------------------- *
7  * This is part of the SimTK biosimulation toolkit originating from *
8  * Simbios, the NIH National Center for Physics-Based Simulation of *
9  * Biological Structures at Stanford, funded under the NIH Roadmap for *
10  * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
11  * *
12  * Portions copyright (c) 2005-12 Stanford University and the Authors. *
13  * Authors: Michael Sherman *
14  * Contributors: Paul Mitiguy *
15  * *
16  * Licensed under the Apache License, Version 2.0 (the "License"); you may *
17  * not use this file except in compliance with the License. You may obtain a *
18  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
19  * *
20  * Unless required by applicable law or agreed to in writing, software *
21  * distributed under the License is distributed on an "AS IS" BASIS, *
22  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
23  * See the License for the specific language governing permissions and *
24  * limitations under the License. *
25  * -------------------------------------------------------------------------- */
26 
32 
33 #include <iosfwd> // Forward declaration of iostream
34 
35 namespace SimTK {
36 
37 //-----------------------------------------------------------------------------
38 // Forward declarations. These are templatized by precision P and and stride S
39 // but always have length 3. TODO: this should be generalized to other lengths.
40 template <class P, int S> class UnitVec;
41 template <class P, int S> class UnitRow;
42 
43 // UnitVec3 is more intelligible name for UnitVec<Real,1>.
47 
48 //-----------------------------------------------------------------------------
54 //-----------------------------------------------------------------------------
55 template <class P, int S>
56 class UnitVec : public Vec<3,P,S> {
57  typedef P RealP;
58 public:
61 
64  UnitVec() : BaseVec(NTraits<P>::getNaN()) {}
65 
68  UnitVec(const UnitVec& u)
69  : BaseVec( static_cast<const BaseVec&>(u) ) {}
70 
73  template <int S2> UnitVec(const UnitVec<P,S2>& u)
74  : BaseVec( static_cast<const typename UnitVec<P,S2>::BaseVec&>(u) ) {}
75 
77  explicit UnitVec(const BaseVec& v) : BaseVec(v/v.norm()) {}
80  template <int S2>
81  explicit UnitVec(const Vec<3,P,S2>& v) : BaseVec(v/v.norm()) {}
82 
86  UnitVec(const RealP& x, const RealP& y, const RealP& z) : BaseVec(x,y,z)
87  { static_cast<BaseVec&>(*this) /= BaseVec::norm(); }
88 
91  UnitVec(const CoordinateAxis& axis) : BaseVec(0)
92  { BaseVec::operator[](axis) = 1; }
93 
97  UnitVec(const CoordinateDirection& dir) : BaseVec(0)
98  { BaseVec::operator[](dir.getAxis()) = RealP(dir.getDirection()); }
99 
102  explicit UnitVec(int axis) : BaseVec(0)
103  { assert(0 <= axis && axis <= 2);
104  BaseVec::operator[](axis) = 1; }
105 
108  { BaseVec::operator=(static_cast<const BaseVec&>(u));
109  return *this; }
110 
113  template <int S2> UnitVec& operator=(const UnitVec<P,S2>& u)
114  { BaseVec::operator=(static_cast<const typename UnitVec<P,S2>::BaseVec&>(u));
115  return *this; }
116 
118  const BaseVec& asVec3() const {return static_cast<const BaseVec&>(*this);}
119 
120  // Override Vec3 methods which preserve length. These return a
121  // packed UnitVec regardless of our stride.
122 
125  UnitVec<P,1> negate() const {return UnitVec<P,1>(-asVec3(),true);}
128  UnitVec<P,1> operator-() const {return negate();}
129 
132  const TransposeType& operator~() const {return *reinterpret_cast<const TransposeType*>(this);}
135  TransposeType& operator~() {return *reinterpret_cast<TransposeType*>(this);}
136 
137  // We have to define these here so that the non-const ones won't be
138  // inherited. We don't trust anyone to write on one element of a UnitVec!
139 
143  const RealP& operator[](int i) const { return BaseVec::operator[](i); }
147  const RealP& operator()(int i) const { return BaseVec::operator()(i); }
148 
154  UnitVec<P,1> abs() const {return UnitVec<P,1>( asVec3().abs(), true );}
155 
159  inline UnitVec<P,1> perp() const;
160 
164  UnitVec(const BaseVec& v, bool) : BaseVec(v) {}
169  template <int S2> UnitVec(const Vec<3,RealP,S2>& v, bool) : BaseVec(v) { }
170 
176  static const UnitVec& getAs(const RealP* p)
177  { return *reinterpret_cast<const UnitVec*>(p); }
178 };
179 
180 
181 template <class P, int S> inline UnitVec<P,1>
183  // Choose the coordinate axis which makes the largest angle
184  // with this vector, that is, has the "least u" along it.
185  const UnitVec<P,1> u(abs()); // reflect to first octant
186  const int minAxis = u[0] <= u[1] ? (u[0] <= u[2] ? 0 : 2)
187  : (u[1] <= u[2] ? 1 : 2);
188  // Cross returns a Vec3 result which is then normalized.
189  return UnitVec<P,1>( *this % UnitVec<P,1>(minAxis) );
190 }
191 
194 template <class P, int S1, int S2> inline bool
196 { return u1.asVec3() == u2.asVec3(); }
197 
201 template <class P, int S1, int S2> inline bool
203 { return !(u1==u2); }
204 
205 //-----------------------------------------------------------------------------
210 //-----------------------------------------------------------------------------
211 template <class P, int S>
212 class UnitRow : public Row<3,P,S> {
213  typedef P RealP;
214 public:
217 
218  UnitRow() : BaseRow(NTraits<P>::getNaN()) { }
219 
221  UnitRow(const UnitRow& u)
222  : BaseRow(static_cast<const BaseRow&>(u)) {}
223 
226  template <int S2> UnitRow(const UnitRow<P,S2>& u)
227  : BaseRow(static_cast<const typename UnitRow<P,S2>::BaseRow&>(u)) { }
228 
231  { BaseRow::operator=(static_cast<const BaseRow&>(u));
232  return *this; }
233 
235  template <int S2> UnitRow& operator=(const UnitRow<P,S2>& u)
236  { BaseRow::operator=(static_cast<const typename UnitRow<P,S2>::BaseRow&>(u));
237  return *this; }
238 
240  explicit UnitRow(const BaseRow& v) : BaseRow(v/v.norm()) {}
243  template <int S2>
244  explicit UnitRow(const Row<3,P,S2>& v) : BaseRow(v/v.norm()) {}
245 
248  UnitRow(const RealP& x, const RealP& y, const RealP& z)
249  : BaseRow(x,y,z)
250  { static_cast<BaseRow&>(*this) /= BaseRow::norm(); }
251 
253  explicit UnitRow(int axis) : BaseRow(0)
254  { assert(0 <= axis && axis <= 2);
255  BaseRow::operator[](axis) = 1; }
256 
258  const BaseRow& asRow3() const {return static_cast<const BaseRow&>(*this);}
259 
260  // Override Row3 methods which preserve length. These return the
261  // packed UnitRow regardless of our stride.
262 
265  UnitRow<P,1> negate() const { return UnitRow<P,1>(-asRow3(),true); }
268  UnitRow<P,1> operator-() const { return negate();}
269 
272  const TransposeType& operator~() const {return *reinterpret_cast<const TransposeType*>(this);}
275  TransposeType& operator~() {return *reinterpret_cast<TransposeType*>(this);}
276 
277  // We have to define these here so that the non-const ones won't be
278  // inherited. We don't trust anyone to write on one element of a UnitRow!
279 
283  const RealP& operator[](int i) const { return BaseRow::operator[](i); }
287  const RealP& operator()(int i) const { return BaseRow::operator()(i); }
288 
294  UnitRow<P,1> abs() const {return UnitRow<P,1>(asRow3().abs(),true);}
295 
299  inline UnitRow<P,1> perp() const;
300 
304  UnitRow( const BaseRow& v, bool ) : BaseRow(v) { }
309  template <int S2> UnitRow( const Row<3,P,S2>& v, bool ) : BaseRow(v) { }
310 
316  static const UnitRow& getAs(const RealP* p)
317  { return *reinterpret_cast<const UnitRow*>(p); }
318 };
319 
320 template <class P, int S>
322  // Choose the coordinate axis which makes the largest angle
323  // with this vector, that is, has the "least u" along it.
324  const UnitRow<P,1> u(abs()); // reflect to first octant
325  const int minAxis = u[0] <= u[1] ? (u[0] <= u[2] ? 0 : 2)
326  : (u[1] <= u[2] ? 1 : 2);
327  // Cross returns a Row3 result which is then normalized.
328  return UnitRow<P,1>(*this % UnitRow<P,1>(minAxis));
329 }
330 
331 
334 template <class P, int S1, int S2> inline bool
336 { return u1.asRow3() == u2.asRow3(); }
337 
341 template <class P, int S1, int S2> inline bool
343 { return !(u1==u2); }
344 
345 //------------------------------------------------------------------------------
346 } // End of namespace SimTK
347 
348 //--------------------------------------------------------------------------
349 #endif // SimTK_UNITVEC_H_
350 //--------------------------------------------------------------------------
351 
352 
UnitVec< P, 1 > perp() const
Return a new unit vector perpendicular to this one but otherwise arbitrary.
Definition: UnitVec.h:182
TAbs abs() const
Elementwise absolute value; that is, the return value has the same dimension as this Vec but with eac...
Definition: Vec.h:345
UnitRow(int axis)
Create a unit axis vector 100 010 001 given 0, 1, or 2.
Definition: UnitVec.h:253
static Vec< M, P, 1 > getNaN()
Return a Vec of the same length and element type as this one but with all elements set to NaN...
Definition: Vec.h:913
UnitRow(const RealP &x, const RealP &y, const RealP &z)
Create a unit row from explicitly specified measure numbers (x,y,z); requires expensive normalization...
Definition: UnitVec.h:248
TransposeType & operator~()
Return a writable reference to this UnitRow reinterpreted as a UnitVec; no computation requires since...
Definition: UnitVec.h:275
UnitVec< Real, 1 > UnitVec3
Definition: UnitVec.h:41
UnitVec(const CoordinateAxis &axis)
Implicit conversion from a coordinate axis XAxis, YAxis, or ZAxis to a UnitVec3. Does not require any...
Definition: UnitVec.h:91
Defines the CoordinateAxis and CoordinateDirection classes.
const E & operator[](int i) const
Select an element of this Vec and return a const reference to it.
Definition: Vec.h:594
UnitVec< double, 1 > dUnitVec3
Definition: UnitVec.h:46
This class is a Vec3 plus an ironclad guarantee either that:
Definition: UnitVec.h:40
const RealP & operator[](int i) const
Return one element of this unit row as a const reference; there is no corresponding writable index fu...
Definition: UnitVec.h:283
UnitVec(const Vec< 3, P, S2 > &v)
Explicit conversion from Vec of any stride to this UnitVec, requiring expensive normalization.
Definition: UnitVec.h:81
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition: Assembler.h:37
static const UnitRow & getAs(const RealP *p)
(Advanced) Reinterpret a given memory location as a UnitRow like this one, without checking – don&#39;t ...
Definition: UnitVec.h:316
UnitRow & operator=(const UnitRow &u)
Copy assignment does not require normalization.
Definition: UnitVec.h:230
UnitVec(const RealP &x, const RealP &y, const RealP &z)
Create a unit vector in the direction of the vector (x,y,z) whose measure numbers are supplied – thi...
Definition: UnitVec.h:86
A CoordinateDirection is a CoordinateAxis plus a direction indicating the positive or negative direct...
Definition: CoordinateAxis.h:244
UnitVec()
Default constructor initializes to all-NaN even in Release mode so that we maintain the above-promise...
Definition: UnitVec.h:64
bool operator!=(const UnitVec< P, S1 > &u1, const UnitVec< P, S2 > &u2)
Compare two UnitVec3 objects and return true unless they are exactly bitwise equal (not very useful)...
Definition: UnitVec.h:202
UnitVec(int axis)
Construct a unit axis vector 100 010 001 given 0,1, or 2; this is not an implicit conversion...
Definition: UnitVec.h:102
UnitVec(const UnitVec &u)
Copy constructor does not require normalization since we know the source is a unit vector...
Definition: UnitVec.h:68
UnitVec< P, 1 > abs() const
Return a new unit vector whose measure numbers are the absolute values of the ones here...
Definition: UnitVec.h:154
UnitRow(const UnitRow &u)
Copy constructor does not require normalization.
Definition: UnitVec.h:221
This class, along with its sister class CoordinateDirection, provides convenient manipulation of the ...
Definition: CoordinateAxis.h:53
bool operator==(const UnitVec< P, S1 > &u1, const UnitVec< P, S2 > &u2)
Compare two UnitVec3 objects for exact, bitwise equality (not very useful).
Definition: UnitVec.h:195
bool operator==(const UnitRow< P, S1 > &u1, const UnitRow< P, S2 > &u2)
Compare two UnitRow3 objects for exact, bitwise equality (not very useful).
Definition: UnitVec.h:335
UnitVec< P, 1 > operator-() const
Returns a new unit vector pointing in the opposite direction from this one.
Definition: UnitVec.h:128
const RealP & operator[](int i) const
Return one element of this unit vector as a const reference; there is no corresponding writable index...
Definition: UnitVec.h:143
UnitRow & operator=(const UnitRow< P, S2 > &u)
Copy assignment from UnitRow with different stride; no computation needed.
Definition: UnitVec.h:235
bool operator!=(const UnitRow< P, S1 > &u1, const UnitRow< P, S2 > &u2)
Compare two UnitRow3 objects and return true unless they are exactly bitwise equal (not very useful)...
Definition: UnitVec.h:342
UnitRow(const Row< 3, P, S2 > &v, bool)
(Advanced) This constructor is only for our friends whom we trust to give us an already-normalized ve...
Definition: UnitVec.h:309
UnitRow(const Row< 3, P, S2 > &v)
Explicit conversion from Row of any stride to UnitRow, requiring expensive normalization.
Definition: UnitVec.h:244
UnitRow()
Definition: UnitVec.h:218
UnitRow(const BaseRow &v)
Explicit conversion from Row to UnitRow, requiring expensive normalization.
Definition: UnitVec.h:240
const E & operator()(int i) const
Same as const operator[] above.
Definition: Vec.h:597
const RealP & operator()(int i) const
Return one element of this unit row as a const reference; there is no corresponding writable index fu...
Definition: UnitVec.h:287
static const UnitVec & getAs(const RealP *p)
(Advanced) Reinterpret a given memory location as a UnitVec like this one, without checking – don&#39;t ...
Definition: UnitVec.h:176
Vec< 3, P, S > BaseVec
Definition: UnitVec.h:59
CoordinateAxis getAxis() const
This is the coordinate axis XAxis, YAxis, or ZAxis contained in this CoordinateDirection. Use getDirection() to determine whether this is the positive or negative direction.
Definition: CoordinateAxis.h:274
This is a fixed-length column vector designed for no-overhead inline computation. ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:605
const BaseVec & asVec3() const
Return a reference to the underlying Vec3 (no copying here).
Definition: UnitVec.h:118
const TransposeType & operator~() const
Return a const reference to this unit vector re-expressed as a unit row; no computational cost...
Definition: UnitVec.h:132
const BaseRow & asRow3() const
Return a const reference to the Row3 underlying this UnitRow.
Definition: UnitVec.h:258
UnitVec & operator=(const UnitVec< P, S2 > &u)
Copy assignment from a UnitVec whose stride differs from this one; no normalization required...
Definition: UnitVec.h:113
UnitRow< P, 1 > abs() const
Return a new UnitRow whose measure numbers are the absolute values of the ones here.
Definition: UnitVec.h:294
UnitVec(const CoordinateDirection &dir)
Implicit conversion from a coordinate axis direction to a UnitVec3. The axis direction is given by on...
Definition: UnitVec.h:97
Vec & operator=(const Vec &src)
Copy assignment operator copies the logically-included elements from the source Vec; gaps due to stri...
Definition: Vec.h:443
UnitRow< P, S > TransposeType
Definition: UnitVec.h:60
UnitVec(const Vec< 3, RealP, S2 > &v, bool)
(Advanced) This constructor is only for our friends whom we trust to give us an already-normalized ve...
Definition: UnitVec.h:169
UnitRow< P, 1 > negate() const
Returns a new unit vector pointing in the opposite direction from this one; does not modify this Unit...
Definition: UnitVec.h:265
const RealP & operator()(int i) const
Return one element of this unit vector as a const reference; there is no corresponding writable index...
Definition: UnitVec.h:147
UnitVec< float, 1 > fUnitVec3
Definition: UnitVec.h:45
UnitRow< P, 1 > perp() const
Return a new UnitRow perpendicular to this one but otherwise arbitrary.
Definition: UnitVec.h:321
float norm(const conjugate< float > &c)
Definition: conjugate.h:775
This file is the user-includeable header to be included in user programs to provide fixed-length Vec ...
TransposeType & operator~()
Return a writable reference to this unit vector re-expressed as a unit row; no computational cost...
Definition: UnitVec.h:135
This is a fixed-length row vector designed for no-overhead inline computation.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:606
UnitVec< P, 1 > negate() const
Returns a new unit vector pointing in the opposite direction from this one; does not modify this Unit...
Definition: UnitVec.h:125
int getDirection() const
Returns 1 or -1 to indicate the direction along the coordinate axis returned by getAxis().
Definition: CoordinateAxis.h:277
CNT< ScalarNormSq >::TSqrt norm() const
Definition: Vec.h:608
UnitVec & operator=(const UnitVec &u)
Copy assignment does not require normalization.
Definition: UnitVec.h:107
UnitVec(const BaseVec &v)
Explicit conversion from Vec to UnitVec, requiring expensive normalization.
Definition: UnitVec.h:77
UnitVec< P, S > TransposeType
Definition: UnitVec.h:216
UnitVec(const BaseVec &v, bool)
(Advanced) This constructor is only for our friends whom we trust to give us an already-normalized ve...
Definition: UnitVec.h:164
This type is used for the transpose of UnitVec, and as the returned row type of a Rotation...
Definition: UnitVec.h:41
UnitRow< P, 1 > operator-() const
Returns a new unit vector pointing in the opposite direction from this one.
Definition: UnitVec.h:268
Row< 3, P, S > BaseRow
Definition: UnitVec.h:215
UnitRow(const UnitRow< P, S2 > &u)
Implicit conversion from UnitRow with different stride; no normalization required.
Definition: UnitVec.h:226
const TransposeType & operator~() const
Return a const reference to this UnitRow reinterpreted as a UnitVec; no computation requires since th...
Definition: UnitVec.h:272
UnitVec(const UnitVec< P, S2 > &u)
Automatic conversion from UnitVec with different stride; no computation required. ...
Definition: UnitVec.h:73
Definition: negator.h:64
UnitRow(const BaseRow &v, bool)
(Advanced) This constructor is only for our friends whom we trust to give us an already-normalized ve...
Definition: UnitVec.h:304