00001
00002
00003
00004
00005
00006
00007
00008
00013 #ifndef quaternion_inverse_h
00014 #define quaternion_inverse_h
00015
00016 #include <cml/quaternion/quaternion_expr.h>
00017 #include <cml/quaternion/quaternion_functions.h>
00018
00019 namespace cml {
00020 namespace et {
00021
00028 template<class ExprT>
00029 class QuaternionInverseOp
00030 {
00031 public:
00032
00033 typedef QuaternionInverseOp<ExprT> expr_type;
00034
00035
00036 typedef unary_expression expr_ary;
00037
00038
00039 typedef expr_type expr_const_reference;
00040
00041
00042 typedef et::ConjugateOp<ExprT> subexpression_type;
00043 typedef ExprTraits<subexpression_type> expr_traits;
00044
00045
00046 typedef ExprTraits<ExprT> arg_traits;
00047 typedef typename arg_traits::const_reference arg_reference;
00048
00049 typedef typename subexpression_type::value_type value_type;
00050 typedef quaternion_result_tag result_tag;
00051 typedef typename subexpression_type::size_tag size_tag;
00052
00053
00054 typedef typename expr_traits::const_reference expr_reference;
00055
00056
00057 typedef typename expr_traits::result_type result_type;
00058
00059
00060 typedef cml::et::not_assignable_tag assignable_tag;
00061
00062
00063 typedef typename result_type::temporary_type temporary_type;
00064
00065
00066 typedef typename result_type::vector_type vector_type;
00067
00068
00069 typedef typename vector_type::subvector_type imaginary_type;
00070
00071
00072 typedef typename result_type::order_type order_type;
00073
00074
00075 public:
00076
00078 enum { array_size = ExprT::array_size };
00079
00081 enum {
00082 W = order_type::W,
00083 X = order_type::X,
00084 Y = order_type::Y,
00085 Z = order_type::Z
00086 };
00087
00088
00089 public:
00090
00092 value_type real() const {
00093 return m_expr.real()/m_norm;
00094 }
00095
00100 imaginary_type imaginary() const {
00101 return m_expr.imaginary()/m_norm;
00102 }
00103
00105 value_type norm() const {
00106 return length_squared();
00107 }
00108
00110 value_type length_squared() const {
00111 return dot(
00112 QuaternionXpr<expr_type>(*this),
00113 QuaternionXpr<expr_type>(*this));
00114 }
00115
00117 value_type length() const {
00118 return std::sqrt(length_squared());
00119 }
00120
00122 temporary_type normalize() const {
00123 temporary_type q(QuaternionXpr<expr_type>(*this));
00124 return q.normalize();
00125 }
00126
00131 value_type operator[](size_t i) const {
00132 return m_expr[i]/m_norm;
00133 }
00134
00135
00136 public:
00137
00139 size_t size() const {
00140 return m_expr.size();
00141 }
00142
00144 expr_reference expression() const { return m_expr; }
00145
00146
00147 public:
00148
00150 explicit QuaternionInverseOp(arg_reference arg)
00151
00152 : m_expr(arg), m_norm(arg.norm()) {}
00153
00155 QuaternionInverseOp(const expr_type& e)
00156 : m_expr(e.m_expr), m_norm(e.m_norm) {}
00157
00158
00159 protected:
00160
00161 subexpression_type m_expr;
00162 value_type m_norm;
00163
00164
00165 private:
00166
00167
00168 expr_type& operator=(const expr_type&);
00169 };
00170
00172 template<class ExprT>
00173 struct ExprTraits< QuaternionInverseOp<ExprT> >
00174 {
00175 typedef QuaternionInverseOp<ExprT> expr_type;
00176 typedef ExprT arg_type;
00177
00178 typedef typename expr_type::value_type value_type;
00179 typedef typename expr_type::expr_const_reference const_reference;
00180 typedef typename expr_type::result_tag result_tag;
00181 typedef typename expr_type::size_tag size_tag;
00182 typedef typename expr_type::result_type result_type;
00183 typedef typename expr_type::assignable_tag assignable_tag;
00184 typedef expr_node_tag node_tag;
00185
00186 value_type get(const expr_type& v, size_t i) const { return v[i]; }
00187 size_t size(const expr_type& e) const { return e.size(); }
00188 };
00189
00190 }
00191
00193 template<typename E, class AT, class OrderT, class CrossT> inline
00194 et::QuaternionXpr< et::QuaternionInverseOp< quaternion<E,AT,OrderT,CrossT> > >
00195 inverse(const quaternion<E,AT,OrderT,CrossT>& arg)
00196 {
00197 typedef et::QuaternionInverseOp< quaternion<E,AT,OrderT,CrossT> > ExprT;
00198 return et::QuaternionXpr<ExprT>(ExprT(arg));
00199 }
00200
00202 template<class XprT> inline
00203 et::QuaternionXpr< et::QuaternionInverseOp<XprT> >
00204 inverse(QUATXPR_ARG_TYPE arg)
00205 {
00206 typedef et::QuaternionInverseOp<XprT> ExprT;
00207 return et::QuaternionXpr<ExprT>(ExprT(arg.expression()));
00208 }
00209
00210
00211
00212
00213 #if 0
00214
00215 template<typename E1, class AT1, typename E2, class AT2, class OT, class CT>
00216 inline typename et::QuaternionPromote<
00217 quaternion<E1,AT1,OT,CT>, quaternion<E2,AT2,OT,CT>
00218 >::temporary_type
00219 operator/(
00220 const quaternion<E1,AT1,OT,CT>& left,
00221 const quaternion<E2,AT2,OT,CT>& right)
00222 {
00223 return left*inverse(right);
00224 }
00225
00227 template<typename E, class AT, class OT, class CT, class XprT>
00228 inline typename et::QuaternionPromote<
00229 quaternion<E,AT,OT,CT>, typename XprT::result_type
00230 >::temporary_type
00231 operator/(
00232 const quaternion<E,AT,OT,CT>& left,
00233 QUATXPR_ARG_TYPE right)
00234 {
00235 return left*inverse(right);
00236 }
00237
00239 template<class XprT, typename E, class AT, class OT, class CT>
00240 inline typename et::QuaternionPromote<
00241 typename XprT::result_type, quaternion<E,AT,OT,CT>
00242 >::temporary_type
00243 operator/(
00244 QUATXPR_ARG_TYPE left,
00245 const quaternion<E,AT,OT,CT>& right)
00246 {
00247 return left*inverse(right);
00248 }
00249
00251 template<class XprT1, class XprT2>
00252 inline typename et::QuaternionPromote<
00253 typename XprT1::result_type, typename XprT2::result_type
00254 >::temporary_type
00255 operator/(
00256 QUATXPR_ARG_TYPE_N(1) left,
00257 QUATXPR_ARG_TYPE_N(2) right)
00258 {
00259 return left*inverse(right);
00260 }
00261 #endif
00262
00263 }
00264
00265 #endif
00266
00267
00268