2 Highly Optimized Object-oriented Many-particle Dynamics -- Blue Edition
3 (HOOMD-blue) Open Source Software License Copyright 2009-2014 The Regents of
4 the University of Michigan All rights reserved.
6 HOOMD-blue may contain modifications ("Contributions") provided, and to which
7 copyright is held, by various Contributors who have granted The Regents of the
8 University of Michigan the right to modify and/or distribute such Contributions.
10 You may redistribute, use, and create derivate works of HOOMD-blue, in source
11 and binary forms, provided you abide by the following conditions:
13 * Redistributions of source code must retain the above copyright notice, this
14 list of conditions, and the following disclaimer both in the code and
15 prominently in any materials provided with the distribution.
17 * Redistributions in binary form must reproduce the above copyright notice, this
18 list of conditions, and the following disclaimer in the documentation and/or
19 other materials provided with the distribution.
21 * All publications and presentations based on HOOMD-blue, including any reports
22 or published results obtained, in whole or in part, with HOOMD-blue, will
23 acknowledge its use according to the terms posted at the time of submission on:
24 http://codeblue.umich.edu/hoomd-blue/citations.html
26 * Any electronic documents citing HOOMD-Blue will link to the HOOMD-Blue website:
27 http://codeblue.umich.edu/hoomd-blue/
29 * Apart from the above required attributions, neither the name of the copyright
30 holder nor the names of HOOMD-blue's contributors may be used to endorse or
31 promote products derived from this software without specific prior written
36 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND
37 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
38 WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND/OR ANY
39 WARRANTIES THAT THIS SOFTWARE IS FREE OF INFRINGEMENT ARE DISCLAIMED.
41 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
42 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
43 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
45 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
46 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
47 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 #include "HOOMDMath.h"
52 #ifndef __VECTOR_MATH_H__
53 #define __VECTOR_MATH_H__
55 /*! \file VectorMath.h
56 \brief Vector and quaternion math operations
59 // need to declare these class methods with __device__ qualifiers when building in nvcc
60 // DEVICE is __host__ __device__ when included in nvcc and blank when included into the host compiler
62 #define DEVICE __device__
67 /*! \addtogroup vecmath
71 /////////////////////////////// vec3 ///////////////////////////////////
74 /*! \tparam Real Data type of the components
76 vec3 defines a simple 3 element vector. The components are available publicly as .x .y and .z. Along with vec3,
77 a number of simple operations are defined to make writing vector math code easier. These include basic element-wise
78 addition, subtraction, division, and multiplication (and += -= *= /=), and similarly division, and
79 multiplication by scalars, and negation. The dot and cross product are also defined.
81 \note Operations like normalize, length, etc... are purposefully **NOT** defined. These hide a sqrt. In high
82 performance code, it is good for the programmer to have to explicitly call expensive operations.
84 template < class Real
>
88 /*! \param _x x-component
92 DEVICE
vec3(const Real
& _x
, const Real
& _y
, const Real
& _z
) : x(_x
), y(_y
), z(_z
)
96 //! Construct a vec3 from a Scalar3
97 /*! \param a Scalar3 to copy
98 This is a convenience function for easy initialization of vec3s from hoomd memory data structures
100 DEVICE
explicit vec3(const Scalar3
& a
) : x(a
.x
), y(a
.y
), z(a
.z
)
104 //! Construct a vec3 from a Scalar4
105 /*! \param a Scalar4 to copy
106 This is a convenience function for easy initialization of vec3s from hoomd memory data structures.
107 \note It drops the w component.
109 DEVICE
explicit vec3(const Scalar4
& a
) : x(a
.x
), y(a
.y
), z(a
.z
)
113 //! Implicit cast from vec3<double> to the current Real
114 DEVICE
vec3(const vec3
<double>& a
) : x(a
.x
), y(a
.y
), z(a
.z
)
118 //! Default construct a 0 vector
119 DEVICE
vec3() : x(0), y(0), z(0)
123 Real x
; //!< x-component of the vector
124 Real y
; //!< y-component of the vector
125 Real z
; //!< z-component of the vector
129 //! Addition of two vec3s
130 /*! \param a First vector
131 \param b Second vector
133 Addition is component wise.
134 \returns The vector (a.x+b.x, a.y+b.y, a.z+b.z).
136 template < class Real
>
137 DEVICE
inline vec3
<Real
> operator+(const vec3
<Real
>& a
, const vec3
<Real
>& b
)
139 return vec3
<Real
>(a
.x
+ b
.x
,
144 //! Subtraction of two vec3s
145 /*! \param a First vector
146 \param b Second vector
148 Subtraction is component wise.
149 \returns The vector (a.x-b.x, a.y-b.y, a.z-b.z).
151 template < class Real
>
152 DEVICE
inline vec3
<Real
> operator-(const vec3
<Real
>& a
, const vec3
<Real
>& b
)
154 return vec3
<Real
>(a
.x
- b
.x
,
159 //! Multiplication of two vec3s
160 /*! \param a First vector
161 \param b Second vector
163 Multiplication is component wise.
164 \returns The vector (a.x*b.x, a.y*b.y, a.z*b.z).
166 template < class Real
>
167 DEVICE
inline vec3
<Real
> operator*(const vec3
<Real
>& a
, const vec3
<Real
>& b
)
169 return vec3
<Real
>(a
.x
* b
.x
,
174 //! Division of two vec3s
175 /*! \param a First vector
176 \param b Second vector
178 Division is component wise.
179 \returns The vector (a.x/b.x, a.y/b.y, a.z/b.z).
181 template < class Real
>
182 DEVICE
inline vec3
<Real
> operator/(const vec3
<Real
>& a
, const vec3
<Real
>& b
)
184 return vec3
<Real
>(a
.x
/ b
.x
,
189 //! Negation of a vec3
192 Negation is component wise.
193 \returns The vector (-a.x, -a.y, -a.z).
195 template < class Real
>
196 DEVICE
inline vec3
<Real
> operator-(const vec3
<Real
>& a
)
198 return vec3
<Real
>(-a
.x
,
204 //! Assignment-addition of two vec3s
205 /*! \param a First vector
206 \param b Second vector
208 Addition is component wise.
209 \returns The vector (a.x += b.x, a.y += b.y, a.z += b.z).
211 template < class Real
>
212 DEVICE
inline vec3
<Real
>& operator +=(vec3
<Real
>& a
, const vec3
<Real
>& b
)
220 //! Assignment-subtraction of two vec3s
221 /*! \param a First vector
222 \param b Second vector
224 Subtraction is component wise.
225 \returns The vector (a.x -= b.x, a.y -= b.y, a.z -= b.z).
227 template < class Real
>
228 DEVICE
inline vec3
<Real
>& operator -=(vec3
<Real
>& a
, const vec3
<Real
>& b
)
236 //! Assignment-multiplication of two vec3s
237 /*! \param a First vector
238 \param b Second vector
240 Multiplication is component wise.
241 \returns The vector (a.x *= b.x, a.y *= b.y, a.z *= b.z).
243 template < class Real
>
244 DEVICE
inline vec3
<Real
>& operator *=(vec3
<Real
>& a
, const vec3
<Real
>& b
)
252 //! Assignment-division of two vec3s
253 /*! \param a First vector
254 \param b Second vector
256 Division is component wise.
257 \returns The vector (a.x /= b.x, a.y /= b.y, a.z /= b.z).
259 template < class Real
>
260 DEVICE
inline vec3
<Real
>& operator /=(vec3
<Real
>& a
, const vec3
<Real
>& b
)
268 //! Multiplication of a vec3 by a scalar
272 Multiplication is component wise.
273 \returns The vector (a.x*b, a.y*b, a.z*b).
275 template < class Real
>
276 DEVICE
inline vec3
<Real
> operator*(const vec3
<Real
>& a
, const Real
& b
)
278 return vec3
<Real
>(a
.x
* b
,
283 //! Multiplication of a vec3 by a scalar
287 Multiplication is component wise.
288 \returns The vector (a.x*b, a.y*b, a.z*b).
290 template < class Real
>
291 DEVICE
inline vec3
<Real
> operator*(const Real
& b
, const vec3
<Real
>& a
)
293 return vec3
<Real
>(a
.x
* b
,
298 //! Division of a vec3 by a scalar
302 Division is component wise.
303 \returns The vector (a.x/b, a.y/b, a.z/b).
305 template < class Real
>
306 DEVICE
inline vec3
<Real
> operator/(const vec3
<Real
>& a
, const Real
& b
)
308 Real q
= Real(1.0)/b
;
312 //! Assignment-multiplication of a vec3 by a scalar
313 /*! \param a First vector
316 Multiplication is component wise.
317 \returns The vector (a.x *= b, a.y *= b, a.z *= b).
319 template < class Real
>
320 DEVICE
inline vec3
<Real
>& operator *=(vec3
<Real
>& a
, const Real
& b
)
328 //! Assignment-division of a vec3 by a scalar
329 /*! \param a First vector
332 Division is component wise.
333 \returns The vector (a.x /= b, a.y /= b, a.z /= b).
335 template < class Real
>
336 DEVICE
inline vec3
<Real
>& operator /=(vec3
<Real
>& a
, const Real
& b
)
344 //! Equality test of two vec3s
345 /*! \param a First vector
346 \param b Second vector
347 \returns true if the two vectors are identically equal, false if they are not
349 template < class Real
>
350 DEVICE
inline bool operator ==(const vec3
<Real
>& a
, const vec3
<Real
>& b
)
352 return (a
.x
== b
.x
) && (a
.y
== b
.y
) && (a
.z
== b
.z
);
355 //! Inequality test of two vec3s
356 /*! \param a First vector
357 \param b Second vector
358 \returns true if the two vectors are not identically equal, and false if they are
360 template < class Real
>
361 DEVICE
inline bool operator !=(const vec3
<Real
>& a
, const vec3
<Real
>& b
)
363 return (a
.x
!= b
.x
) || (a
.y
!= b
.y
) || (a
.z
!= b
.z
);
366 //! dot product of two vec3s
367 /*! \param a First vector
368 \param b Second vector
370 \returns the dot product a.x*b.x + a.y*b.y + a.z*b.z.
372 template < class Real
>
373 DEVICE
inline Real
dot(const vec3
<Real
>& a
, const vec3
<Real
>& b
)
375 return (a
.x
*b
.x
+ a
.y
*b
.y
+ a
.z
*b
.z
);
378 //! cross product of two vec3s
379 /*! \param a First vector
380 \param b Second vector
382 \returns the cross product (a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x).
384 template < class Real
>
385 DEVICE
inline vec3
<Real
> cross(const vec3
<Real
>& a
, const vec3
<Real
>& b
)
387 return vec3
<Real
>(a
.y
* b
.z
- a
.z
* b
.y
,
388 a
.z
* b
.x
- a
.x
* b
.z
,
389 a
.x
* b
.y
- a
.y
* b
.x
);
392 //! Convenience function for converting a vec3 to a Scalar3
393 DEVICE
inline Scalar3
vec_to_scalar3(const vec3
<Scalar
>& a
)
395 return make_scalar3(a
.x
, a
.y
, a
.z
);
398 //! Convenience function for converting a vec3 and a w to a Scalar4
399 DEVICE
inline Scalar4
vec_to_scalar4(const vec3
<Scalar
>& a
, Scalar w
)
401 return make_scalar4(a
.x
, a
.y
, a
.z
, w
);
404 /////////////////////////////// vec2 ///////////////////////////////////
407 /*! \tparam Real Data type of the components
409 vec2 defines a simple 2 element vector. The components are available publicly as .x and .y. Along with vec2,
410 a number of simple operations are defined to make writing vector math code easier. These include basic element-wise
411 addition, subtraction, division, and multiplication (and += -= *= /=), and similarly division, and
412 multiplication by scalars, and negation. The dot product is also defined.
414 \note Operations like normalize, length, etc... are purposefully **NOT** defined. These hide a sqrt. In high
415 performance code, it is good for the programmer to have to explicitly call expensive operations.
417 template < class Real
>
421 /*! \param _x x-component
422 \param _y y-component
424 DEVICE
vec2(const Real
& _x
, const Real
& _y
) : x(_x
), y(_y
)
428 //! Default construct a 0 vector
429 DEVICE
vec2() : x(0), y(0)
433 Real x
; //!< x-component of the vector
434 Real y
; //!< y-component of the vector
438 //! Addition of two vec2s
439 /*! \param a First vector
440 \param b Second vector
442 Addition is component wise.
443 \returns The vector (a.x+b.x, a.y+b.y).
445 template < class Real
>
446 DEVICE
inline vec2
<Real
> operator+(const vec2
<Real
>& a
, const vec2
<Real
>& b
)
448 return vec2
<Real
>(a
.x
+ b
.x
,
452 //! Subtraction of two vec2s
453 /*! \param a First vector
454 \param b Second vector
456 Subtraction is component wise.
457 \returns The vector (a.x-b.x, a.y-b.y).
459 template < class Real
>
460 DEVICE
inline vec2
<Real
> operator-(const vec2
<Real
>& a
, const vec2
<Real
>& b
)
462 return vec2
<Real
>(a
.x
- b
.x
,
466 //! Multiplication of two vec2s
467 /*! \param a First vector
468 \param b Second vector
470 Multiplication is component wise.
471 \returns The vector (a.x*b.x, a.y*b.y).
473 template < class Real
>
474 DEVICE
inline vec2
<Real
> operator*(const vec2
<Real
>& a
, const vec2
<Real
>& b
)
476 return vec2
<Real
>(a
.x
* b
.x
,
480 //! Division of two vec2s
481 /*! \param a First vector
482 \param b Second vector
484 Division is component wise.
485 \returns The vector (a.x/b.x, a.y/b.y).
487 template < class Real
>
488 DEVICE
inline vec2
<Real
> operator/(const vec2
<Real
>& a
, const vec2
<Real
>& b
)
490 return vec2
<Real
>(a
.x
/ b
.x
,
494 //! Negation of a vec2
497 Negation is component wise.
498 \returns The vector (-a.x, -a.y).
500 template < class Real
>
501 DEVICE
inline vec2
<Real
> operator-(const vec2
<Real
>& a
)
503 return vec2
<Real
>(-a
.x
,
508 //! Assignment-addition of two vec2s
509 /*! \param a First vector
510 \param b Second vector
512 Addition is component wise.
513 \returns The vector (a.x += b.x, a.y += b.y).
515 template < class Real
>
516 DEVICE
inline vec2
<Real
>& operator +=(vec2
<Real
>& a
, const vec2
<Real
>& b
)
523 //! Assignment-subtraction of two vec2s
524 /*! \param a First vector
525 \param b Second vector
527 Subtraction is component wise.
528 \returns The vector (a.x -= b.x, a.y -= b.y).
530 template < class Real
>
531 DEVICE
inline vec2
<Real
>& operator -=(vec2
<Real
>& a
, const vec2
<Real
>& b
)
538 //! Assignment-multiplication of two vec2s
539 /*! \param a First vector
540 \param b Second vector
542 Multiplication is component wise.
543 \returns The vector (a.x *= b.x, a.y *= b.y).
545 template < class Real
>
546 DEVICE
inline vec2
<Real
>& operator *=(vec2
<Real
>& a
, const vec2
<Real
>& b
)
553 //! Assignment-division of two vec2s
554 /*! \param a First vector
555 \param b Second vector
557 Division is component wise.
558 \returns The vector (a.x /= b.x, a.y /= b.y).
560 template < class Real
>
561 DEVICE
inline vec2
<Real
>& operator /=(vec2
<Real
>& a
, const vec2
<Real
>& b
)
568 //! Multiplication of a vec2 by a scalar
572 Multiplication is component wise.
573 \returns The vector (a.x*b, a.y*b).
575 template < class Real
>
576 DEVICE
inline vec2
<Real
> operator*(const vec2
<Real
>& a
, const Real
& b
)
578 return vec2
<Real
>(a
.x
* b
,
582 //! Multiplication of a vec2 by a scalar
586 Multiplication is component wise.
587 \returns The vector (a.x*b, a.y*b).
589 template < class Real
>
590 DEVICE
inline vec2
<Real
> operator*(const Real
& b
, const vec2
<Real
>& a
)
592 return vec2
<Real
>(a
.x
* b
,
596 //! Division of a vec2 by a scalar
600 Division is component wise.
601 \returns The vector (a.x/b, a.y/b, a.z/b).
603 template < class Real
>
604 DEVICE
inline vec2
<Real
> operator/(const vec2
<Real
>& a
, const Real
& b
)
606 Real q
= Real(1.0)/b
;
610 //! Assignment-multiplication of a vec2 by a scalar
611 /*! \param a First vector
614 Multiplication is component wise.
615 \returns The vector (a.x *= b, a.y *= b).
617 template < class Real
>
618 DEVICE
inline vec2
<Real
>& operator *=(vec2
<Real
>& a
, const Real
& b
)
625 //! Assignment-division of a vec2 by a scalar
626 /*! \param a First vector
629 Division is component wise.
630 \returns The vector (a.x /= b, a.y /= b).
632 template < class Real
>
633 DEVICE
inline vec2
<Real
>& operator /=(vec2
<Real
>& a
, const Real
& b
)
640 //! Equality test of two vec2s
641 /*! \param a First vector
642 \param b Second vector
643 \returns true if the two vectors are identically equal, false if they are not
645 template < class Real
>
646 DEVICE
inline bool operator ==(const vec2
<Real
>& a
, const vec2
<Real
>& b
)
648 return (a
.x
== b
.x
) && (a
.y
== b
.y
);
651 //! Inequality test of two vec2s
652 /*! \param a First vector
653 \param b Second vector
654 \returns true if the two vectors are not identically equal, false if they are
656 template < class Real
>
657 DEVICE
inline bool operator !=(const vec2
<Real
>& a
, const vec2
<Real
>& b
)
659 return (a
.x
!= b
.x
) || (a
.y
!= b
.y
);
662 //! dot product of two vec2s
663 /*! \param a First vector
664 \param b Second vector
666 \returns the dot product a.x*b.x + a.y*b.y.
668 template < class Real
>
669 DEVICE
inline Real
dot(const vec2
<Real
>& a
, const vec2
<Real
>& b
)
671 return (a
.x
*b
.x
+ a
.y
*b
.y
);
674 //! vec2 perpendicular operation
676 \returns a vector perpendicular to *a* (a.y, -a.x)
678 template < class Real
>
679 DEVICE
inline vec2
<Real
> perp(const vec2
<Real
>& a
)
681 return vec2
<Real
>(-a
.y
, a
.x
);
684 //! vec2 perpendicular dot product
685 /*! \param a first vector
686 \param b second vector
687 \returns the perpendicular dot product of a and b
689 template < class Real
>
690 DEVICE
inline Real
perpdot(const vec2
<Real
>& a
, const vec2
<Real
>& b
)
692 return dot(perp(a
), b
);
696 /////////////////////////////// quat ///////////////////////////////////
699 /*! \tparam Real Data type of the components
701 quat defines a quaternion. The standard representation (https://en.wikipedia.org/wiki/Quaternion) is
702 a1 + bi + cj + dk, or as a 4-vector (a, b, c, d). A more compact an expressive representation is to use
703 a scalar and a 3-vector (s, v) where v = (b,c,d). This is the representation that quat uses.
705 The following operators are defined for quaternions.
711 - quat * vec3 (vec3 is promoted to quaternion (0,v))
712 - vec3 * quat (vec3 is promoted to quaternion (0,v))
717 For more info on this representation and its relation to rotation, see:
718 http://people.csail.mit.edu/bkph/articles/Quaternions.pdf
721 \note normalize is purposefully **NOT** defined. It would hide hide a sqrt. In high
722 performance code, it is good for the programmer to have to explicitly call expensive operations. In lieu of this,
723 norm2 is provided, which computes the norm of a quaternion, squared.
725 template < class Real
>
728 //! Construct a quaternion
729 /*! \param _s scalar component
730 \param _v vector component
732 DEVICE
quat(const Real
& _s
, const vec3
<Real
>& _v
) : s(_s
), v(_v
)
736 //! Construct a quat from a Scalar4
737 /*! \param a Scalar4 to copy
739 This is a convenience function for easy initialization of quats from hoomd memory data structures.
741 \note For some unfathomable reason, hoomd stores a quaternion as (x, (y,z,w)). Be aware of this when using the
744 DEVICE
explicit quat(const Scalar4
& a
) : s(a
.x
), v(vec3
<Real
>(a
.y
, a
.z
, a
.w
))
748 //! Implicit cast from quat<double> to the current Real
749 DEVICE
quat(const quat
<double>& a
) : s(a
.s
), v(a
.v
)
753 //! Default construct a unit quaternion
754 DEVICE
quat() : s(1), v(vec3
<Real
>(0,0,0))
758 //! Construct a quat from an axis and an angle.
759 /*! \param axis angle to represent
760 \param theta angle to represent
762 This is a convenience function for easy initialization of rotmat3s from an axis and an angle.
763 The rotmat3 will initialize to the same rotation as the angle around the specified axis.
765 DEVICE
static quat
fromAxisAngle(const vec3
<Real
>& axis
, const Real
& theta
)
767 quat
<Real
> q(fast::cos(theta
/2.0), (Real
)fast::sin(theta
/2.0) * axis
);
771 Real s
; //!< scalar component
772 vec3
<Real
> v
; //!< vector component
775 //! Multiplication of a quat by a scalar
779 Multiplication is component wise.
780 \returns The quaternion (b*a.s, b*a.v).
782 template < class Real
>
783 DEVICE
inline quat
<Real
> operator*(const Real
& b
, const quat
<Real
>& a
)
785 return quat
<Real
>(b
* a
.s
,
789 //! Multiplication of a quat by a scalar
793 Multiplication is component wise.
794 \returns The quaternion (a.s*b, a.v*b).
796 template < class Real
>
797 DEVICE
inline quat
<Real
> operator*(const quat
<Real
>& a
, const Real
& b
)
799 return quat
<Real
>(a
.s
* b
,
804 //! Addition of two quats
805 /*! \param a First quat
808 Addition is component wise.
809 \returns The quaternion (a.s + b.s, a.v+b.v).
811 template < class Real
>
812 DEVICE
inline quat
<Real
> operator+(const quat
<Real
>& a
, const quat
<Real
>& b
)
814 return quat
<Real
>(a
.s
+ b
.s
,
818 //! Assignment-addition of two quats
819 /*! \param a First quat
822 Addition is component wise.
823 \returns The quaternion (a.s += b.s, a.v += b.v).
825 template < class Real
>
826 DEVICE
inline quat
<Real
>& operator +=(quat
<Real
>& a
, const quat
<Real
>& b
)
833 //! Subtraction of two quats
834 /*! \param a First quat
837 Subtraction is component wise.
838 \returns The quaternion (a.s - b.s, a.v - b.v).
840 template < class Real
>
841 DEVICE
inline quat
<Real
> operator-(const quat
<Real
>& a
, const quat
<Real
>& b
)
843 return quat
<Real
>(a
.s
- b
.s
,
847 //! Assignment-addition of two quats
848 /*! \param a First quat
851 Subtraction is component wise.
852 \returns The quaternion (a.s -= b.s, a.v -= b.v).
854 template < class Real
>
855 DEVICE
inline quat
<Real
>& operator -=(quat
<Real
>& a
, const quat
<Real
>& b
)
862 //! Multiplication of two quats
863 /*! \param a First quat
866 Multiplication is quaternion multiplication, defined as the cross product minus the dot product.
867 (Ref. http://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation#Quaternions_briefly)
868 When quaternions are being used for rotation, the composition of two rotation operations can be
869 replaced by the quaternion product of the second rotation quaternion times the first.
870 Note that quaternion multiplication is non-commutative.
871 \returns The quaternion
872 (a.s * b.s − dot(a.v, b.v), a.s*b.v + b.s * a.v + cross(a.v, b.v)).
874 template < class Real
>
875 DEVICE
inline quat
<Real
> operator*(const quat
<Real
>& a
, const quat
<Real
>& b
)
877 return quat
<Real
>(a
.s
*b
.s
- dot(a
.v
, b
.v
),
878 a
.s
*b
.v
+ b
.s
* a
.v
+ cross(a
.v
,b
.v
));
881 //! Multiplication of a vector by a quaternion
885 Multiplication is quaternion multiplication. The vector is promoted to a quaternion (0,a)
887 \returns The quaternion (a.s * b.s − dot(a.v, b.v), a.s*b.v + b.s * a.v + cross(a.v, b.v)).
889 template < class Real
>
890 DEVICE
inline quat
<Real
> operator*(const vec3
<Real
>& a
, const quat
<Real
>& b
)
892 return quat
<Real
>(0,a
) * b
;
895 //! Multiplication of a quaternion by a vector
899 Multiplication is quaternion multiplication. The vector is promoted to a quaternion (0,b)
901 \returns The quaternion (a.s * b.s − dot(a.v, b.v), a.s*b.v + b.s * a.v + cross(a.v, b.v)).
903 template < class Real
>
904 DEVICE
inline quat
<Real
> operator*(const quat
<Real
>& a
, const vec3
<Real
>& b
)
906 return a
* quat
<Real
>(0,b
);
909 //! norm squared of a quaternion
912 \returns the norm of the quaternion, squared. (a.s*a.s + dot(a.v,a.v))
914 template < class Real
>
915 DEVICE
inline Real
norm2(const quat
<Real
>& a
)
917 return (a
.s
*a
.s
+ dot(a
.v
,a
.v
));
920 //! conjugate of a quaternion
923 \returns the conjugate of the quaternion. (a.s, -a.v)
925 template < class Real
>
926 DEVICE
inline quat
<Real
> conj(const quat
<Real
>& a
)
928 return quat
<Real
>(a
.s
, -a
.v
);
931 //! rotate a vec3 by a quaternion
932 /*! \param a quat (should be a unit quaternion (Cos(theta/2), Sin(theta/2)*axis_unit_vector))
933 \param b vector to rotate
935 \returns the vector rotated by the quaternion, equivalent to the vector component of a*b*conj(a);
937 template < class Real
>
938 DEVICE
inline vec3
<Real
> rotate(const quat
<Real
>& a
, const vec3
<Real
>& b
)
940 //quat<Real> result = a*b*conj(a);
943 // note: this version below probably results in fewer math operations. Need to double check that it works when
944 // testing. I guesstimate only 20 clock ticks to rotate a vector with this code.
945 // it comes from http://people.csail.mit.edu/bkph/articles/Quaternions.pdf
946 return (a
.s
*a
.s
- dot(a
.v
, a
.v
))*b
+ 2*a
.s
*cross(a
.v
,b
) + 2*dot(a
.v
,b
)*a
.v
;
948 // from http://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation
949 // a suggested method for 15 mults and 15 adds, also in the above pdf:
950 // return b + cross( (Real(2) * a.v), (cross(a.v,b) + (a.s * b)) );
953 //! rotate a vec2 by a quaternion
954 /*! \param a quat (should be a unit quaternion (Cos(theta/2), Sin(theta/2)*axis_unit_vector))
955 \param b vector to rotate
957 \returns the vector rotated by the quaternion, equivalent to the vector component of a*b*conj(a);
959 *b* is promoted to a 3d vector with z=0 for the rotation.
961 template < class Real
>
962 DEVICE
inline vec2
<Real
> rotate(const quat
<Real
>& a
, const vec2
<Real
>& b
)
964 vec3
<Real
> b3(b
.x
, b
.y
, Real(0.0));
965 //b3 = (a*b3*conj(a)).v;
967 // note: this version below probably results in fewer math operations. Need to double check that it works when
968 // testing. I guesstimate only 20 clock ticks to rotate a vector with this code.
969 // it comes from http://people.csail.mit.edu/bkph/articles/Quaternions.pdf
970 b3
= (a
.s
*a
.s
- dot(a
.v
, a
.v
))*b3
+ 2*a
.s
*cross(a
.v
,b3
) + 2*dot(a
.v
,b3
)*a
.v
;
972 // from http://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation
973 // a suggested method for 15 mults and 15 adds, also in the above pdf:
974 // b3 = b3 + cross( (Real(2) * a.v), (cross(a.v,b3) + (a.s * b3)) );
975 return vec2
<Real
>(b3
.x
, b3
.y
);
979 //! Convenience function for converting a quat to a Scalar4
980 /*! \param a quat to convert
981 \returns a Scalar4 in hoomd format
983 \note For some unfathomable reason, hoomd stores a quaternion as (x, (y,z,w)). Be aware of this when using the
986 DEVICE
inline Scalar4
quat_to_scalar4(const quat
<Scalar
>& a
)
988 return make_scalar4(a
.s
, a
.v
.x
, a
.v
.y
, a
.v
.z
);
991 /////////////////////////////// rotmat2 ////////////////////////////////
993 //! 2x2 rotation matrix
994 /*! This is not a general 2x2 matrix class, but is specific to rotation matrices. It is designed for the use case
995 where the same quaternion is repeatedly applied to many vectors in an inner loop. Using a rotation matrix
996 decreases the number of FLOPs needed at the (potential) cost of increased register pressure. Both methods
997 should be benchmarked to evaluate the actual performance trade-offs.
999 The following operators are defined for rotmat2s.
1001 - rotmat2(quat) - *constructs from a quaternion*
1003 template < class Real
>
1006 //! Construct a quaternion
1007 /*! \param _row0 First row
1008 \param _row1 Second row
1010 DEVICE
rotmat2(const vec2
<Real
>& _row0
, const vec2
<Real
>& _row1
) : row0(_row0
), row1(_row1
)
1014 //! Construct a rotmat2 from a quat
1015 /*! \param q quaternion to represent
1017 This is a convenience function for easy initialization of rotmat2s from quats. The rotmat2 will initialize to
1018 the same rotation as the quaternion.
1020 formula from http://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation
1023 DEVICE
explicit rotmat2(const quat
<Real
>& q
)
1030 row0
.x
= a
*a
+ b
*b
- c
*c
- d
*d
;
1031 row0
.y
= 2*b
*c
- 2*a
*d
;
1032 row1
.x
= 2*b
*c
+ 2*a
*d
;
1033 row1
.y
= a
*a
- b
*b
+ c
*c
- d
*d
;
1036 //! Default construct an identity matrix
1037 DEVICE
rotmat2() : row0(vec2
<Real
>(1,0)), row1(vec2
<Real
>(0,1))
1041 //! Construct a rotmat2 from a float. formula from http://en.wikipedia.org/wiki/Rotation_matrix
1042 /*! \param theta angle to represent
1044 This is a convenience function for easy initialization of rotmat2s from angles. The rotmat2 will initialize to
1045 the same rotation as the angle.
1048 DEVICE
static rotmat2
fromAngle(const Real
& theta
)
1052 row0
.x
= fast::cos(theta
);
1053 row0
.y
= -fast::sin(theta
);
1054 row1
.x
= fast::sin(theta
);
1055 row1
.y
= fast::cos(theta
);
1056 return rotmat2
<Real
>(row0
, row1
);
1059 vec2
<Real
> row0
; //!< First row
1060 vec2
<Real
> row1
; //!< Second row
1063 //! Matrix vector multiplication
1068 Multiplication is matrix multiplication, where the vector is represented as a column vector.
1070 template < class Real
>
1071 DEVICE
inline vec2
<Real
> operator*(const rotmat2
<Real
>& A
, const vec2
<Real
>& b
)
1073 return vec2
<Real
>(dot(A
.row0
, b
),
1077 //! Transpose a rotmat2
1079 \returns the transpose of A
1081 A rotation matrix has an inverse equal to its transpose. There may be times where an algorithm needs to undo a
1082 rotation, so the transpose method is provided.
1084 template < class Real
>
1085 DEVICE
inline rotmat2
<Real
> transpose(const rotmat2
<Real
>& A
)
1087 return rotmat2
<Real
>(vec2
<Real
>(A
.row0
.x
, A
.row1
.x
),
1088 vec2
<Real
>(A
.row0
.y
, A
.row1
.y
));
1091 /////////////////////////////// rotmat3 ////////////////////////////////
1093 //! 3x3 rotation matrix
1094 /*! This is not a general 3x3 matrix class, but is specific to rotation matrices. It is designed for the use case
1095 where the same quaternion is repeatedly applied to many vectors in an inner loop. Using a rotation matrix
1096 decreases the number of FLOPs needed at the (potential) cost of increased register pressure. Both methods
1097 should be benchmarked to evaluate the actual performance trade-offs.
1099 The following operators are defined for rotmat3s.
1101 - rotmat3(quat) - *constructs from a quaternion*
1103 \note Do not yet depend on the internal representation by rows. Future versions may store data in a different way.
1105 template < class Real
>
1108 //! Construct a quaternion
1109 /*! \param _row0 First row
1110 \param _row1 Second row
1111 \param _row2 Third row
1113 DEVICE
rotmat3(const vec3
<Real
>& _row0
, const vec3
<Real
>& _row1
, const vec3
<Real
>& _row2
)
1114 : row0(_row0
), row1(_row1
), row2(_row2
)
1118 //! Construct a rotmat3 from a quat
1119 /*! \param q quaternion to represent
1121 This is a convenience function for easy initialization of rotmat3s from quats. The rotmat3 will initialize to
1122 the same rotation as the quaternion.
1124 DEVICE
explicit rotmat3(const quat
<Real
>& q
)
1126 // formula from http://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation
1132 row0
.x
= a
*a
+ b
*b
- c
*c
- d
*d
;
1133 row0
.y
= 2*b
*c
- 2*a
*d
;
1134 row0
.z
= 2*b
*d
+ 2*a
*c
;
1136 row1
.x
= 2*b
*c
+ 2*a
*d
;
1137 row1
.y
= a
*a
- b
*b
+ c
*c
- d
*d
;
1138 row1
.z
= 2*c
*d
- 2*a
*b
;
1140 row2
.x
= 2*b
*d
- 2*a
*c
;
1141 row2
.y
= 2*c
*d
+ 2*a
*b
;
1142 row2
.z
= a
*a
- b
*b
- c
*c
+ d
*d
;
1145 //! Default construct an identity matrix
1146 DEVICE
rotmat3() : row0(vec3
<Real
>(1,0,0)), row1(vec3
<Real
>(0,1,0)), row2(vec3
<Real
>(0,0,1))
1150 //! Construct a rotmat3 from an axis and an angle.
1151 /*! \param axis angle to represent
1152 \param theta angle to represent
1154 This is a convenience function for easy initialization of rotmat3s from an axis and an angle.
1155 The rotmat3 will initialize to the same rotation as the angle around the specified axis.
1157 DEVICE
static rotmat3
fromAxisAngle(const vec3
<Real
>& axis
, const Real
& theta
)
1159 return rotmat3
<Real
>(quat
<Real
>::fromAxisAngle(axis
, theta
));
1162 vec3
<Real
> row0
; //!< First row
1163 vec3
<Real
> row1
; //!< Second row
1164 vec3
<Real
> row2
; //!< Third row
1167 //! Matrix vector multiplication
1172 Multiplication is matrix multiplication, where the vector is represented as a column vector.
1174 template < class Real
>
1175 DEVICE
inline vec3
<Real
> operator*(const rotmat3
<Real
>& A
, const vec3
<Real
>& b
)
1177 return vec3
<Real
>(dot(A
.row0
, b
),
1182 //! Transpose a rotmat3
1184 \returns the transpose of A
1186 A rotation matrix has an inverse equal to its transpose. There may be times where an algorithm needs to undo a
1187 rotation, so the transpose method is provided.
1189 template < class Real
>
1190 DEVICE
inline rotmat3
<Real
> transpose(const rotmat3
<Real
>& A
)
1192 return rotmat3
<Real
>(vec3
<Real
>(A
.row0
.x
, A
.row1
.x
, A
.row2
.x
),
1193 vec3
<Real
>(A
.row0
.y
, A
.row1
.y
, A
.row2
.y
),
1194 vec3
<Real
>(A
.row0
.z
, A
.row1
.z
, A
.row2
.z
));
1197 /////////////////////////////// generic operations /////////////////////////////////
1199 //! Vector projection
1200 /*! \param a first vector
1201 \param b second vector
1202 \returns the projection of a onto b
1203 \note projection() can be applied to 2d or 3d vectors
1205 template < class Vec
>
1206 DEVICE
inline Vec
project(const Vec
& a
, const Vec
& b
)
1208 return dot(a
,b
)/dot(b
,b
) * b
;
1211 //! Swap two data structures
1212 /*! \param a first object
1213 \param b second object
1215 \note can be applied to vec2, vec3, quaternions, or anything with a sufficiently deep copy constructor.
1217 template < class T
>
1218 DEVICE
inline void swap(T
& a
, T
&b
)
1229 #endif //__VECTOR_MATH_H__