Simbody 3.7
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
35namespace 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.
40template <class P, int S> class UnitVec;
41template <class P, int S> class UnitRow;
42
43// UnitVec3 is more intelligible name for UnitVec<Real,1>.
47
48//-----------------------------------------------------------------------------
54//-----------------------------------------------------------------------------
55template <class P, int S>
56class UnitVec : public Vec<3,P,S> {
57public:
60
64
67 UnitVec(const UnitVec& u)
68 : BaseVec( static_cast<const BaseVec&>(u) ) {}
69
72 template <int S2> UnitVec(const UnitVec<P,S2>& u)
73 : BaseVec( static_cast<const typename UnitVec<P,S2>::BaseVec&>(u) ) {}
74
76 explicit UnitVec(const BaseVec& v) : BaseVec(v/v.norm()) {}
79 template <int S2>
80 explicit UnitVec(const Vec<3,P,S2>& v) : BaseVec(v/v.norm()) {}
81
85 UnitVec(const P& x, const P& y, const P& z) : BaseVec(x,y,z)
86 { static_cast<BaseVec&>(*this) /= BaseVec::norm(); }
87
90 UnitVec(const CoordinateAxis& axis) : BaseVec(0)
91 { BaseVec::operator[](axis) = 1; }
92
97 { BaseVec::operator[](dir.getAxis()) = P(dir.getDirection()); }
98
101 explicit UnitVec(int axis) : BaseVec(0)
102 { assert(0 <= axis && axis <= 2);
103 BaseVec::operator[](axis) = 1; }
104
107 { BaseVec::operator=(static_cast<const BaseVec&>(u));
108 return *this; }
109
112 template <int S2> UnitVec& operator=(const UnitVec<P,S2>& u)
113 { BaseVec::operator=(static_cast<const typename UnitVec<P,S2>::BaseVec&>(u));
114 return *this; }
115
117 const BaseVec& asVec3() const {return static_cast<const BaseVec&>(*this);}
118
119 // Override Vec3 methods which preserve length. These return a
120 // packed UnitVec regardless of our stride.
121
124 UnitVec<P,1> negate() const {return UnitVec<P,1>(-asVec3(),true);}
127 UnitVec<P,1> operator-() const {return negate();}
128
131 const TransposeType& operator~() const {return *reinterpret_cast<const TransposeType*>(this);}
134 TransposeType& operator~() {return *reinterpret_cast<TransposeType*>(this);}
135
136 // We have to define these here so that the non-const ones won't be
137 // inherited. We don't trust anyone to write on one element of a UnitVec!
138
142 const P& operator[](int i) const { return BaseVec::operator[](i); }
146 const P& operator()(int i) const { return BaseVec::operator()(i); }
147
153 UnitVec<P,1> abs() const {return UnitVec<P,1>( asVec3().abs(), true );}
154
158 inline UnitVec<P,1> perp() const;
159
163 UnitVec(const BaseVec& v, bool) : BaseVec(v) {}
168 template <int S2> UnitVec(const Vec<3,P,S2>& v, bool) : BaseVec(v) { }
169
175 static const UnitVec& getAs(const P* p)
176 { return *reinterpret_cast<const UnitVec*>(p); }
177};
178
179
180template <class P, int S> inline UnitVec<P,1>
182 // Choose the coordinate axis which makes the largest angle
183 // with this vector, that is, has the "least u" along it.
184 const UnitVec<P,1> u(abs()); // reflect to first octant
185 const int minAxis = u[0] <= u[1] ? (u[0] <= u[2] ? 0 : 2)
186 : (u[1] <= u[2] ? 1 : 2);
187 // Cross returns a Vec3 result which is then normalized.
188 return UnitVec<P,1>( *this % UnitVec<P,1>(minAxis) );
189}
190
193template <class P, int S1, int S2> inline bool
195{ return u1.asVec3() == u2.asVec3(); }
196
200template <class P, int S1, int S2> inline bool
202{ return !(u1==u2); }
203
204//-----------------------------------------------------------------------------
209//-----------------------------------------------------------------------------
210template <class P, int S>
211class UnitRow : public Row<3,P,S> {
212public:
215
217
219 UnitRow(const UnitRow& u)
220 : BaseRow(static_cast<const BaseRow&>(u)) {}
221
224 template <int S2> UnitRow(const UnitRow<P,S2>& u)
225 : BaseRow(static_cast<const typename UnitRow<P,S2>::BaseRow&>(u)) { }
226
229 { BaseRow::operator=(static_cast<const BaseRow&>(u));
230 return *this; }
231
233 template <int S2> UnitRow& operator=(const UnitRow<P,S2>& u)
234 { BaseRow::operator=(static_cast<const typename UnitRow<P,S2>::BaseRow&>(u));
235 return *this; }
236
238 explicit UnitRow(const BaseRow& v) : BaseRow(v/v.norm()) {}
241 template <int S2>
242 explicit UnitRow(const Row<3,P,S2>& v) : BaseRow(v/v.norm()) {}
243
246 UnitRow(const P& x, const P& y, const P& z)
247 : BaseRow(x,y,z)
248 { static_cast<BaseRow&>(*this) /= BaseRow::norm(); }
249
251 explicit UnitRow(int axis) : BaseRow(0)
252 { assert(0 <= axis && axis <= 2);
253 BaseRow::operator[](axis) = 1; }
254
256 const BaseRow& asRow3() const {return static_cast<const BaseRow&>(*this);}
257
258 // Override Row3 methods which preserve length. These return the
259 // packed UnitRow regardless of our stride.
260
263 UnitRow<P,1> negate() const { return UnitRow<P,1>(-asRow3(),true); }
266 UnitRow<P,1> operator-() const { return negate();}
267
270 const TransposeType& operator~() const {return *reinterpret_cast<const TransposeType*>(this);}
273 TransposeType& operator~() {return *reinterpret_cast<TransposeType*>(this);}
274
275 // We have to define these here so that the non-const ones won't be
276 // inherited. We don't trust anyone to write on one element of a UnitRow!
277
281 const P& operator[](int i) const { return BaseRow::operator[](i); }
285 const P& operator()(int i) const { return BaseRow::operator()(i); }
286
292 UnitRow<P,1> abs() const {return UnitRow<P,1>(asRow3().abs(),true);}
293
297 inline UnitRow<P,1> perp() const;
298
302 UnitRow( const BaseRow& v, bool ) : BaseRow(v) { }
307 template <int S2> UnitRow( const Row<3,P,S2>& v, bool ) : BaseRow(v) { }
308
314 static const UnitRow& getAs(const P* p)
315 { return *reinterpret_cast<const UnitRow*>(p); }
316};
317
318template <class P, int S>
320 // Choose the coordinate axis which makes the largest angle
321 // with this vector, that is, has the "least u" along it.
322 const UnitRow<P,1> u(abs()); // reflect to first octant
323 const int minAxis = u[0] <= u[1] ? (u[0] <= u[2] ? 0 : 2)
324 : (u[1] <= u[2] ? 1 : 2);
325 // Cross returns a Row3 result which is then normalized.
326 return UnitRow<P,1>(*this % UnitRow<P,1>(minAxis));
327}
328
329
332template <class P, int S1, int S2> inline bool
334{ return u1.asRow3() == u2.asRow3(); }
335
339template <class P, int S1, int S2> inline bool
341{ return !(u1==u2); }
342
343//------------------------------------------------------------------------------
344} // End of namespace SimTK
345
346//--------------------------------------------------------------------------
347#endif // SimTK_UNITVEC_H_
348//--------------------------------------------------------------------------
349
350
Defines the CoordinateAxis and CoordinateDirection classes.
This file is the user-includeable header to be included in user programs to provide fixed-length Vec ...
This class, along with its sister class CoordinateDirection, provides convenient manipulation of the ...
Definition: CoordinateAxis.h:53
A CoordinateDirection is a CoordinateAxis plus a direction indicating the positive or negative direct...
Definition: CoordinateAxis.h:244
int getDirection() const
Returns 1 or -1 to indicate the direction along the coordinate axis returned by getAxis().
Definition: CoordinateAxis.h:277
CoordinateAxis getAxis() const
This is the coordinate axis XAxis, YAxis, or ZAxis contained in this CoordinateDirection....
Definition: CoordinateAxis.h:274
Definition: NTraits.h:436
This is a fixed-length row vector designed for no-overhead inline computation.
Definition: Row.h:132
Row & operator=(const Row &src)
Definition: Row.h:319
static Row< N, P, 1 > getNaN()
Return a Row of the same length and element type as this one but with all elements set to NaN.
Definition: Row.h:715
CNT< ScalarNormSq >::TSqrt norm() const
Definition: Row.h:456
const E & operator[](int i) const
Definition: Row.h:449
const E & operator()(int i) const
Definition: Row.h:451
This type is used for the transpose of UnitVec, and as the returned row type of a Rotation.
Definition: UnitVec.h:211
UnitRow(const P &x, const P &y, const P &z)
Create a unit row from explicitly specified measure numbers (x,y,z); requires expensive normalization...
Definition: UnitVec.h:246
UnitRow()
Definition: UnitVec.h:216
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:263
TransposeType & operator~()
Return a writable reference to this UnitRow reinterpreted as a UnitVec; no computation requires since...
Definition: UnitVec.h:273
UnitRow & operator=(const UnitRow &u)
Copy assignment does not require normalization.
Definition: UnitVec.h:228
const P & 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:281
UnitRow(const UnitRow< P, S2 > &u)
Implicit conversion from UnitRow with different stride; no normalization required.
Definition: UnitVec.h:224
UnitRow(const Row< 3, P, S2 > &v)
Explicit conversion from Row of any stride to UnitRow, requiring expensive normalization.
Definition: UnitVec.h:242
static const UnitRow & getAs(const P *p)
(Advanced) Reinterpret a given memory location as a UnitRow like this one, without checking – don't u...
Definition: UnitVec.h:314
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:333
UnitRow(const BaseRow &v)
Explicit conversion from Row to UnitRow, requiring expensive normalization.
Definition: UnitVec.h:238
const BaseRow & asRow3() const
Return a const reference to the Row3 underlying this UnitRow.
Definition: UnitVec.h:256
UnitRow(int axis)
Create a unit axis vector 100 010 001 given 0, 1, or 2.
Definition: UnitVec.h:251
UnitRow(const UnitRow &u)
Copy constructor does not require normalization.
Definition: UnitVec.h:219
Row< 3, P, S > BaseRow
Definition: UnitVec.h:213
UnitVec< P, S > TransposeType
Definition: UnitVec.h:214
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:307
UnitRow< P, 1 > abs() const
Return a new UnitRow whose measure numbers are the absolute values of the ones here.
Definition: UnitVec.h:292
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:340
UnitRow & operator=(const UnitRow< P, S2 > &u)
Copy assignment from UnitRow with different stride; no computation needed.
Definition: UnitVec.h:233
const TransposeType & operator~() const
Return a const reference to this UnitRow reinterpreted as a UnitVec; no computation requires since th...
Definition: UnitVec.h:270
const P & 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:285
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:302
UnitRow< P, 1 > operator-() const
Returns a new unit vector pointing in the opposite direction from this one.
Definition: UnitVec.h:266
UnitRow< P, 1 > perp() const
Return a new UnitRow perpendicular to this one but otherwise arbitrary.
Definition: UnitVec.h:319
UnitRow< P, S > TransposeType
Definition: UnitVec.h:59
UnitVec< P, 1 > abs() const
Return a new unit vector whose measure numbers are the absolute values of the ones here.
Definition: UnitVec.h:153
const P & operator()(int i) const
Return one element of this unit vector as a const reference; there is no corresponding writable index...
Definition: UnitVec.h:146
TransposeType & operator~()
Return a writable reference to this unit vector re-expressed as a unit row; no computational cost.
Definition: UnitVec.h:134
UnitVec(const UnitVec &u)
Copy constructor does not require normalization since we know the source is a unit vector.
Definition: UnitVec.h:67
UnitVec< P, 1 > perp() const
Return a new unit vector perpendicular to this one but otherwise arbitrary.
Definition: UnitVec.h:181
UnitVec & operator=(const UnitVec< P, S2 > &u)
Copy assignment from a UnitVec whose stride differs from this one; no normalization required.
Definition: UnitVec.h:112
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:201
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:194
const P & operator[](int i) const
Return one element of this unit vector as a const reference; there is no corresponding writable index...
Definition: UnitVec.h:142
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:163
UnitVec()
Default constructor initializes to all-NaN even in Release mode so that we maintain the above-promise...
Definition: UnitVec.h:63
const BaseVec & asVec3() const
Return a reference to the underlying Vec3 (no copying here).
Definition: UnitVec.h:117
UnitVec(const Vec< 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:168
UnitVec(const BaseVec &v)
Explicit conversion from Vec to UnitVec, requiring expensive normalization.
Definition: UnitVec.h:76
UnitVec(const Vec< 3, P, S2 > &v)
Explicit conversion from Vec of any stride to this UnitVec, requiring expensive normalization.
Definition: UnitVec.h:80
UnitVec(const UnitVec< P, S2 > &u)
Automatic conversion from UnitVec with different stride; no computation required.
Definition: UnitVec.h:72
UnitVec(const CoordinateDirection &dir)
Implicit conversion from a coordinate axis direction to a UnitVec3. The axis direction is given by on...
Definition: UnitVec.h:96
UnitVec< P, 1 > operator-() const
Returns a new unit vector pointing in the opposite direction from this one.
Definition: UnitVec.h:127
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:101
Vec< 3, P, S > BaseVec
Definition: UnitVec.h:58
static const UnitVec & getAs(const P *p)
(Advanced) Reinterpret a given memory location as a UnitVec like this one, without checking – don't u...
Definition: UnitVec.h:175
const TransposeType & operator~() const
Return a const reference to this unit vector re-expressed as a unit row; no computational cost.
Definition: UnitVec.h:131
UnitVec & operator=(const UnitVec &u)
Copy assignment does not require normalization.
Definition: UnitVec.h:106
UnitVec(const P &x, const P &y, const P &z)
Create a unit vector in the direction of the vector (x,y,z) whose measure numbers are supplied – this...
Definition: UnitVec.h:85
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:124
UnitVec(const CoordinateAxis &axis)
Implicit conversion from a coordinate axis XAxis, YAxis, or ZAxis to a UnitVec3. Does not require any...
Definition: UnitVec.h:90
This is a fixed-length column vector designed for no-overhead inline computation.
Definition: Vec.h:184
Vec & operator=(const Vec &src)
Copy assignment operator copies the logically-included elements from the source Vec; gaps due to stri...
Definition: Vec.h:445
CNT< ScalarNormSq >::TSqrt norm() const
Definition: Vec.h:610
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:915
const E & operator[](int i) const
Select an element of this Vec and return a const reference to it.
Definition: Vec.h:596
const E & operator()(int i) const
Same as const operator[] above.
Definition: Vec.h:599
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition: Assembler.h:37
RowVectorBase< typename CNT< ELEM >::TAbs > abs(const RowVectorBase< ELEM > &v)
Definition: VectorMath.h:120
UnitVec< double, 1 > dUnitVec3
Definition: UnitVec.h:46
UnitVec< Real, 1 > UnitVec3
Definition: UnitVec.h:44
UnitVec< float, 1 > fUnitVec3
Definition: UnitVec.h:45