template< typename T > Aftr::AxisAngleT::AxisAngleT() noexcept {} template< typename T > Aftr::AxisAngleT::AxisAngleT( VectorT const& axis, T angleDeg ) noexcept : axis_( axis.normalizeMe() ), deg_( AxisAngleImpl::modulus_deg_180_to_neg180(angleDeg) ) { if( deg_ < 0 ) { deg_ = -deg_; axis_ = -axis_; } } template< typename T > Aftr::AxisAngleT::AxisAngleT( Aftr::AxisAngleT const& toCopy ) noexcept { *this = toCopy; } template< typename T > Aftr::AxisAngleT::AxisAngleT( Aftr::VectorT const& rodrigues_rot_vec ) noexcept { T angleDeg = rodrigues_rot_vec.length() * T( Aftr::RADtoDEGd ); deg_ = AxisAngleImpl::modulus_deg_180_to_neg180( angleDeg ); this->axis_ = rodrigues_rot_vec.normalizeMe(); if( this->axis_.isEqual( { 0,0,0 } ) ) this->axis_ = { 0,0,1 }; //length / magnitude will always be positive on Vector } template< typename T > Aftr::AxisAngleT& Aftr::AxisAngleT::operator=( const Aftr::AxisAngleT& aa ) noexcept { if( this != &aa ) { this->axis_ = aa.axis_; this->deg_ = aa.deg_; } return *this; } template< typename T > bool Aftr::AxisAngleT::isEqual( AxisAngleT const& b, T epsilon ) const noexcept { return AxisAngleImpl::isEqual( *this, b, epsilon ); } //template< typename T > //void Aftr::AxisAngleT::toRotationMatrix(T m[]) const //{ // m[3] = m[7] = m[11] = 0; // m[12] = m[13] = m[14] = 0; // m[15] = 1; // m[0] = a * a + b * b - c * c - d * d; // m[1] = T(2.0) * b * c - T(2.0) * a * d; // m[2] = T(2.0) * a * c + T(2.0) * b * d; // m[4] = T(2.0) * a * d + T(2.0) * b * c; // m[5] = a * a - b * b + c * c - d * d; // m[6] = T(2.0) * c * d - T(2.0) * a * b; // m[8] = T(2.0) * b * d - T(2.0) * a * c; // m[9] = T(2.0) * a * b + T(2.0) * c * d; // m[10] = a * a - b * b - c * c + d * d; //} template< typename T > std::string Aftr::AxisAngleT::toString( size_t length) const { return AxisAngleImpl::toString( *this, length ); } template< typename T > Aftr::VectorT const& Aftr::AxisAngleT::axis() const noexcept { return this->axis_; } template< typename T > T Aftr::AxisAngleT::deg() const noexcept { return this->deg_; } template< typename T > T Aftr::AxisAngleT::rad() const noexcept { return this->deg_ * T( Aftr::DEGtoRADd ); } template< typename T > Aftr::VectorT Aftr::AxisAngleT::toRodrigues() const noexcept { //if the radian measure is nearly exactly 180, like 180.00000000003, //we have to be careful to handle the normalization into rodrigues properly VectorT rod{ this->axis_ * this->rad() }; return rod; } template< typename T > Aftr::VectorT Aftr::AxisAngleT::toVec() const noexcept { VectorT v = VectorT{ T(1),T(0),T(0) }.rotate( this->axis_, this->rad() ); return v; }