1 /* -*- C++ -*- ------------------------------------------------------------
3 Copyright (c) 2007 Jesse Anders and Demian Nave http://cmldev.net/
5 The Configurable Math Library (CML) is distributed under the terms of the
6 Boost Software License, v1.0 (see cml/LICENSE for details).
8 *-----------------------------------------------------------------------*/
10 * @brief Defines an operator for quaternion conjugation.
16 #include <cml/quaternion/quaternion_expr.h>
21 /** An expression node for conjugating a quaternion. */
27 typedef ConjugateOp
<ExprT
> expr_type
;
29 /* Record ary-ness of the expression: */
30 typedef unary_expression expr_ary
;
32 /* Copy the expression by value into higher-up expressions: */
33 typedef expr_type expr_const_reference
;
35 typedef typename
ExprT::value_type value_type
;
36 typedef quaternion_result_tag result_tag
;
37 typedef typename
ExprT::size_tag size_tag
;
39 /* Store the expression traits for the subexpression: */
40 typedef ExprTraits
<ExprT
> expr_traits
;
42 /* Reference type for the subexpression: */
43 typedef typename
expr_traits::const_reference expr_reference
;
45 /* Get the result type (same as for subexpression): */
46 typedef typename
expr_traits::result_type result_type
;
48 /* For matching by assignability: */
49 typedef cml::et::not_assignable_tag assignable_tag
;
51 /* Get the temporary type: */
52 typedef typename
result_type::temporary_type temporary_type
;
54 /* Get the vector type: */
55 typedef typename
result_type::vector_type vector_type
;
57 /* Get the imaginary part type: */
58 typedef typename
vector_type::subvector_type imaginary_type
;
60 /* Record the order type: */
61 typedef typename
result_type::order_type order_type
;
66 /** Record result size as an enum. */
67 enum { array_size
= ExprT::array_size
};
69 /** Localize the ordering as an enum. */
80 /** Return the real part of the expression. */
81 value_type
real() const {
85 /** Return the vector part of the expression. */
86 imaginary_type
imaginary() const {
87 return -m_expr
.imaginary();
90 /** Return the Cayley norm of the expression. */
91 value_type
norm() const {
92 return length_squared();
95 /** Return square of the quaternion length. */
96 value_type
length_squared() const {
98 QuaternionXpr
<expr_type
>(*this),
99 QuaternionXpr
<expr_type
>(*this));
102 /** Return the quaternion length. */
103 value_type
length() const {
104 return std::sqrt(length_squared());
107 /** Return the result as a normalized quaternion. */
108 temporary_type
normalize() const {
109 temporary_type
q(QuaternionXpr
<expr_type
>(*this));
110 return q
.normalize();
113 /** Compute conjugated result at index i.
115 * The conjugate of quaternion s + v is s - v.
117 value_type
operator[](size_t i
) const {
118 return (i
== W
) ? m_expr
[W
] : - m_expr
[i
] ;
124 /** Return size of this expression (same as argument's size). */
125 size_t size() const {
126 return m_expr
.size();
129 /** Return reference to contained expression. */
130 expr_reference
expression() const { return m_expr
; }
135 /** Construct from the subexpression. */
136 explicit ConjugateOp(expr_reference expr
) : m_expr(expr
) {}
138 /** Copy constructor. */
139 ConjugateOp(const expr_type
& e
) : m_expr(e
.m_expr
) {}
144 expr_reference m_expr
;
149 /* Cannot be assigned to: */
150 expr_type
& operator=(const expr_type
&);
153 /** Expression traits class for ConjugateOp<>. */
154 template<class ExprT
>
155 struct ExprTraits
< ConjugateOp
<ExprT
> >
157 typedef ConjugateOp
<ExprT
> expr_type
;
158 typedef ExprT arg_type
;
160 typedef typename
expr_type::value_type value_type
;
161 typedef typename
expr_type::expr_const_reference const_reference
;
162 typedef typename
expr_type::result_tag result_tag
;
163 typedef typename
expr_type::size_tag size_tag
;
164 typedef typename
expr_type::result_type result_type
;
165 typedef typename
expr_type::assignable_tag assignable_tag
;
166 typedef expr_node_tag node_tag
;
168 value_type
get(const expr_type
& v
, size_t i
) const { return v
[i
]; }
169 size_t size(const expr_type
& e
) const { return e
.size(); }
174 /** Conjugation of a quaternion. */
175 template<typename E
, class AT
, class OT
, class CT
> inline
176 et::QuaternionXpr
< et::ConjugateOp
< quaternion
<E
,AT
,OT
,CT
> > >
177 conjugate(const quaternion
<E
,AT
,OT
,CT
>& arg
)
179 typedef et::ConjugateOp
< quaternion
<E
,AT
,OT
,CT
> > ExprT
;
180 return et::QuaternionXpr
<ExprT
>(ExprT(arg
));
183 /** Conjugation of a QuaternionXpr. */
184 template<class XprT
> inline
185 et::QuaternionXpr
< et::ConjugateOp
<XprT
> >
186 conjugate(QUATXPR_ARG_TYPE arg
)
188 typedef et::ConjugateOp
<XprT
> ExprT
;
189 return et::QuaternionXpr
<ExprT
>(ExprT(arg
.expression()));
196 // -------------------------------------------------------------------------