diff --git a/etk/math/Matrix2.cpp b/etk/math/Matrix2.cpp new file mode 100644 index 0000000..cb5b814 --- /dev/null +++ b/etk/math/Matrix2.cpp @@ -0,0 +1,244 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ + +#include + +std::ostream& etk::operator <<(std::ostream& _os, const etk::Matrix2& _obj) { + _os << "{"; + _os << _obj.m_mat[0] << ","; + _os << _obj.m_mat[4] << ","; + _os << _obj.m_mat[1] << ","; + _os << _obj.m_mat[3] << ","; + _os << _obj.m_mat[2] << ","; + _os << _obj.m_mat[5] << "}"; + return _os; +} + +void etk::Matrix2::identity() { + m_mat[0] = 1.0; + m_mat[1] = 0.0; + m_mat[2] = 0.0; + m_mat[3] = 1.0; + m_mat[4] = 0.0; + m_mat[5] = 0.0; +} + +etk::Matrix2::Matrix2() { + // TODO: Remove this ... + identity(); +} +etk::Matrix2::Matrix2(const etk::Matrix2& _obj) { + for(int32_t iii=0; iii<2*3 ; iii++) { + m_mat[iii] = _obj.m_mat[iii]; + } +} + +etk::Matrix2::Matrix2(float _sx, + float _shy, + float _shx, + float _sy, + float _tx, + float _ty) { + m_mat[0] = _sx; + m_mat[4] = _shy; + m_mat[1] = _shx; + m_mat[3] = _sy; + m_mat[2] = _tx; + m_mat[5] = _ty; +} + +etk::Matrix2::Matrix2(const float* _values) { + if (_values == nullptr) { + identity(); + return; + } + m_mat[0] = _values[0]; + m_mat[4] = _values[1]; + m_mat[1] = _values[2]; + m_mat[3] = _values[3]; + m_mat[2] = _values[4]; + m_mat[5] = _values[5]; +} + +etk::Matrix2::Matrix2(const double* _values) { + if (_values == nullptr) { + identity(); + return; + } + m_mat[0] = _values[0]; + m_mat[4] = _values[1]; + m_mat[1] = _values[2]; + m_mat[3] = _values[3]; + m_mat[2] = _values[4]; + m_mat[5] = _values[5]; +} + +etk::Matrix2::~Matrix2() { + +} + +const etk::Matrix2& etk::Matrix2::operator= (const etk::Matrix2& _obj ) { + for(int32_t iii=0; iii<2*3 ; ++iii) { + m_mat[iii] = _obj.m_mat[iii]; + } + return *this; +} + +bool etk::Matrix2::operator== (const etk::Matrix2& _obj) const { + for(int32_t iii=0; iii<2*3 ; ++iii) { + if(m_mat[iii] != _obj.m_mat[iii]) { + return false; + } + } + return true; +} + +bool etk::Matrix2::operator!= (const etk::Matrix2& _obj) const { + for(int32_t iii=0; iii<2*3 ; ++iii) { + if(m_mat[iii] != _obj.m_mat[iii]) { + return true; + } + } + return false; +} + +const etk::Matrix2& etk::Matrix2::operator+= (const etk::Matrix2& _obj) { + for(int32_t iii=0; iii<2*3 ; ++iii) { + m_mat[iii] += _obj.m_mat[iii]; + } + return *this; +} + +etk::Matrix2 etk::Matrix2::operator+ (const etk::Matrix2& _obj) const { + etk::Matrix2 tmpp(*this); + tmpp += _obj; + return tmpp; +} + +const etk::Matrix2& etk::Matrix2::operator-= (const etk::Matrix2& _obj) { + for(int32_t iii=0; iii<2*3 ; ++iii) { + m_mat[iii] -= _obj.m_mat[iii]; + } + return *this; +} + +etk::Matrix2 etk::Matrix2::operator- (const etk::Matrix2& _obj) const { + etk::Matrix2 tmpp(*this); + tmpp += _obj; + return tmpp; +} + +const etk::Matrix2& etk::Matrix2::operator *= (const etk::Matrix2& _obj) { + float t0 = m_mat[0] * _obj.m_mat[0] + m_mat[4] * _obj.m_mat[1]; + float t2 = m_mat[1] * _obj.m_mat[0] + m_mat[3] * _obj.m_mat[1]; + float t4 = m_mat[2] * _obj.m_mat[0] + m_mat[5] * _obj.m_mat[1] + _obj.m_mat[2]; + m_mat[4] = m_mat[0] * _obj.m_mat[4] + m_mat[4] * _obj.m_mat[3]; + m_mat[3] = m_mat[1] * _obj.m_mat[4] + m_mat[3] * _obj.m_mat[3]; + m_mat[5] = m_mat[2] * _obj.m_mat[4] + m_mat[5] * _obj.m_mat[3] + _obj.m_mat[5]; + m_mat[0] = t0; + m_mat[1] = t2; + m_mat[2] = t4; + return *this; +} + +etk::Matrix2 etk::Matrix2::operator * (const etk::Matrix2& _obj) { + etk::Matrix2 tmp(*this); + tmp *= _obj; + return tmp; +} + +etk::Matrix2 etk::Matrix2::operator ~ () const { + etk::Matrix2 tmp(*this); + tmp.invert(); + return tmp; +} + +void etk::Matrix2::flipX() { + m_mat[0] = -m_mat[0]; + m_mat[4] = -m_mat[4]; + m_mat[2] = -m_mat[2]; +} + +void etk::Matrix2::flipY() { + m_mat[1] = -m_mat[1]; + m_mat[3] = -m_mat[3]; + m_mat[5] = -m_mat[5]; +} + +void etk::Matrix2::scale(const vec2& _vect) { + m_mat[0] *= _vect.x(); + m_mat[1] *= _vect.x(); + m_mat[2] *= _vect.x(); + m_mat[4] *= _vect.y(); + m_mat[3] *= _vect.y(); + m_mat[5] *= _vect.y(); +} + +void etk::Matrix2::scale(float _value) { + m_mat[0] *= _value; + m_mat[1] *= _value; + m_mat[2] *= _value; + m_mat[4] *= _value; + m_mat[3] *= _value; + m_mat[5] *= _value; +} + +void etk::Matrix2::rotate(float _angleRad) { + float ca = cos(_angleRad); + float sa = sin(_angleRad); + float t0 = m_mat[0] * ca - m_mat[4] * sa; + float t2 = m_mat[1] * ca - m_mat[3] * sa; + float t4 = m_mat[2] * ca - m_mat[5] * sa; + m_mat[4] = m_mat[0] * sa + m_mat[4] * ca; + m_mat[3] = m_mat[1] * sa + m_mat[3] * ca; + m_mat[5] = m_mat[2] * sa + m_mat[5] * ca; + m_mat[0] = t0; + m_mat[1] = t2; + m_mat[2] = t4; +} + +void etk::Matrix2::translate(const vec2& _vect) { + m_mat[2] += _vect.x(); + m_mat[5] += _vect.y(); +} + +float etk::Matrix2::determinant() const { + return m_mat[0] * m_mat[3] - m_mat[4] * m_mat[1]; +} + +void etk::Matrix2::invert() { + float det = 1.0f / determinant(); + float t0 = m_mat[3] * det; + m_mat[3] = m_mat[0] * det; + m_mat[4] = -m_mat[4] * det; + m_mat[1] = -m_mat[1] * det; + float t4 = -m_mat[2] * t0 - m_mat[5] * m_mat[1]; + m_mat[5] = -m_mat[2] * m_mat[4] - m_mat[5] * m_mat[3]; + m_mat[0] = t0; + m_mat[2] = t4; +} + +etk::Matrix2 etk::mat2Rotate(float _angleRad) { + return Matrix2(cos(_angleRad), sin(_angleRad), -sin(_angleRad), cos(_angleRad), 0.0, 0.0); +}; + +etk::Matrix2 etk::mat2Scale(const vec2& _scale) { + return Matrix2(_scale.x(), 0.0, 0.0, _scale.y(), 0.0, 0.0); +}; + +etk::Matrix2 etk::mat2Scale(float _scale) { + return Matrix2(_scale, 0.0, 0.0, _scale, 0.0, 0.0); +}; + +etk::Matrix2 etk::mat2Translate(const vec2& _translate) { + return Matrix2(1.0, 0.0, 0.0, 1.0, _translate.x(), _translate.y()); +}; + +etk::Matrix2 etk::mat2Skew(const vec2& _skew) { + return Matrix2(1.0, tan(_skew.y()), tan(_skew.x()), 1.0, 0.0, 0.0); +}; diff --git a/etk/math/Matrix2.h b/etk/math/Matrix2.h new file mode 100644 index 0000000..b65ce25 --- /dev/null +++ b/etk/math/Matrix2.h @@ -0,0 +1,133 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ + +#ifndef __ETK_TYPES_MATRIX2_H__ +#define __ETK_TYPES_MATRIX2_H__ + +#include +#include +namespace etk { + class Matrix2 { + public: + /* + * sx shx tx + * sy shy ty + */ + float m_mat[2*3]; + /** + * @brief Load Identity matrix + */ + void identity(); + public: + /***************************************************** + * Constructor + *****************************************************/ + Matrix2(); + Matrix2(const Matrix2& _obj); + Matrix2(float _sx, + float _shy, + float _shx, + float _sy, + float _tx, + float _ty); + Matrix2(const float* _values); + Matrix2(const double* _values); + /***************************************************** + * Destructor + *****************************************************/ + ~Matrix2(); + /***************************************************** + * = assigment + *****************************************************/ + const Matrix2& operator= (const Matrix2& _obj ); + /***************************************************** + * == operator + *****************************************************/ + bool operator== (const Matrix2& _obj) const; + /***************************************************** + * != operator + *****************************************************/ + bool operator!= (const Matrix2& _obj) const; + /***************************************************** + * += operator + *****************************************************/ + const Matrix2& operator+= (const Matrix2& _obj); + /***************************************************** + * + operator + *****************************************************/ + Matrix2 operator+ (const Matrix2& _obj) const; + /***************************************************** + * -= operator + *****************************************************/ + const Matrix2& operator-= (const Matrix2& _obj); + /***************************************************** + * - operator + *****************************************************/ + Matrix2 operator- (const Matrix2& _obj) const; + /***************************************************** + * *= operator + *****************************************************/ + const Matrix2& operator *= (const Matrix2& _obj); + /***************************************************** + * * operator + *****************************************************/ + Matrix2 operator * (const Matrix2& _obj); + /***************************************************** + * ~ operator + *****************************************************/ + Matrix2 operator ~ () const; + /** + * @brief Flip the mathix threw the X axis + */ + void flipX(); + /** + * @brief Flip the mathix threw the Y axis + */ + void flipY(); + /** + * @brief Scale the current Matrix. + * @param[in] _vect Vector to scale matrix. + * @param[in] _value Single value to scale in X andf Y. + */ + void scale(const vec2& _vect); + //! @previous + void scale(float _value); + /** + * @brief Makes a rotation matrix. + * @param[in] _angleRad angle to apply. + */ + void rotate(float _angleRad); + /** + * @brief Makes a translation of the matrix + * @param[in] _vect Translation to apply. + */ + void translate(const vec2& _vect); + /** + * @brief Computes the determinant of the matrix. + * @return The determinent Value. + */ + float determinant() const; + /** + * @brief Inverts the matrix. + * @note The determinant must be != 0, otherwithe the matrix can't be inverted. + * @return The inverted matrix. + */ + void invert(); + }; + Matrix2 mat2Rotate(float _angleRad); + Matrix2 mat2Scale(const vec2& _scale); + Matrix2 mat2Scale(float _scale); + Matrix2 mat2Translate(const vec2& _translate); + Matrix2 mat2Skew(const vec2& _skew); + std::ostream& operator <<(std::ostream& _os, const etk::Matrix2& _obj); +} +// simplify using of matrix ... +typedef etk::Matrix2 mat2; + +#endif +