]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/affinematrix2d.cpp
Add wxAffineMatrix2D and related classes.
[wxWidgets.git] / src / common / affinematrix2d.cpp
diff --git a/src/common/affinematrix2d.cpp b/src/common/affinematrix2d.cpp
new file mode 100644 (file)
index 0000000..977f683
--- /dev/null
@@ -0,0 +1,179 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        affinematrix2d.cpp
+// Purpose:     implementation of wxAffineMatrix2D
+// Author:      Based on wxTransformMatrix by Chris Breeze, Julian Smart
+// Created:     2011-04-05
+// Copyright:   (c) wxWidgets team
+// Licence:     wxWidgets licence
+///////////////////////////////////////////////////////////////////////////////
+
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/affinematrix2d.h"
+#include "wx/math.h"
+
+// sets the matrix to the respective values
+void wxAffineMatrix2D::Set(const wxMatrix2D &mat2D, const wxPoint2DDouble &tr)
+{
+    m_11 = mat2D.m_11;
+    m_12 = mat2D.m_12;
+    m_21 = mat2D.m_21;
+    m_22 = mat2D.m_22;
+    m_tx = tr.m_x;
+    m_ty = tr.m_y;
+}
+
+// gets the component valuess of the matrix
+void wxAffineMatrix2D::Get(wxMatrix2D *mat2D, wxPoint2DDouble *tr) const
+{
+    mat2D->m_11 = m_11;
+    mat2D->m_12 = m_12;
+    mat2D->m_21 = m_21;
+    mat2D->m_22 = m_22;
+
+    if ( tr )
+    {
+        tr->m_x = m_tx;
+        tr->m_y = m_ty;
+    }
+}
+
+// concatenates the matrix
+// | t.m_11  t.m_12  0 |   | m_11  m_12   0 |
+// | t.m_21  t.m_22  0 | x | m_21  m_22   0 |
+// | t.m_tx  t.m_ty  1 |   | m_tx  m_ty   1 |
+void wxAffineMatrix2D::Concat(const wxAffineMatrix2DBase &t)
+{
+    wxMatrix2D mat;
+    wxPoint2DDouble tr;
+    t.Get(&mat, &tr);
+
+    m_tx += tr.m_x*m_11 + tr.m_y*m_21;
+    m_ty += tr.m_x*m_12 + tr.m_y*m_22;
+    wxDouble e11 = mat.m_11*m_11 + mat.m_12*m_21;
+    wxDouble e12 = mat.m_11*m_12 + mat.m_12*m_22;
+    wxDouble e21 = mat.m_21*m_11 + mat.m_22*m_21;
+    m_22 = mat.m_21*m_12 + mat.m_22*m_22;
+    m_11 = e11;
+    m_12 = e12;
+    m_21 = e21;
+}
+
+// makes this its inverse matrix.
+// Invert
+// | m_11  m_12   0 |
+// | m_21  m_22   0 |
+// | m_tx  m_ty   1 |
+bool wxAffineMatrix2D::Invert()
+{
+    const wxDouble det = m_11*m_22 - m_12*m_21;
+
+    if ( !det )
+        return false;
+
+    wxDouble ex = (m_21*m_ty - m_22*m_tx) / det;
+    m_ty = (-m_11*m_ty + m_12*m_tx) / det;
+    m_tx = ex;
+    wxDouble e11 = m_22 / det;
+    m_12 = -m_12 / det;
+    m_21 = -m_21 / det;
+    m_22 = m_11 / det;
+    m_11 = e11;
+
+    return true;
+}
+
+// returns true if the elements of the transformation matrix are equal
+bool wxAffineMatrix2D::IsEqual(const wxAffineMatrix2DBase& t) const
+{
+    wxMatrix2D mat;
+    wxPoint2DDouble tr;
+    t.Get(&mat, &tr);
+
+    return m_11 == mat.m_11 && m_12 == mat.m_12 &&
+           m_21 == mat.m_21 && m_22 == mat.m_22 &&
+           m_tx == tr.m_x && m_ty == tr.m_y;
+}
+
+//
+// transformations
+//
+
+// add the translation to this matrix
+void wxAffineMatrix2D::Translate(wxDouble dx, wxDouble dy)
+{
+    m_tx += dx;
+    m_ty += dy;
+}
+
+// add the scale to this matrix
+// | xScale   0      0 |   | m_11  m_12   0 |
+// |   0    yScale   0 | x | m_21  m_22   0 |
+// |   0      0      1 |   | m_tx  m_ty   1 |
+void wxAffineMatrix2D::Scale(wxDouble xScale, wxDouble yScale)
+{
+    m_11 *= xScale;
+    m_12 *= xScale;
+    m_21 *= yScale;
+    m_22 *= yScale;
+}
+
+// add the rotation to this matrix (counter clockwise, radians)
+// | cos   -sin   0 |   | m_11  m_12   0 |
+// | sin    cos   0 | x | m_21  m_22   0 |
+// |  0      0    1 |   | m_tx  m_ty   1 |
+void wxAffineMatrix2D::Rotate(wxDouble ccRadians)
+{
+    wxDouble c = cos(ccRadians);
+    wxDouble s = sin(ccRadians);
+
+    wxDouble e11 = c*m_11 - s*m_21;
+    wxDouble e12 = c*m_12 - s*m_22;
+    m_21 = s*m_11 + c*m_21;
+    m_22 = s*m_12 + c*m_22;
+    m_11 = e11;
+    m_12 = e12;
+}
+
+//
+// apply the transforms
+//
+
+// applies that matrix to the point
+//                           | m_11  m_12   0 |
+// | src.m_x  src._my  1 | x | m_21  m_22   0 |
+//                           | m_tx  m_ty   1 |
+wxPoint2DDouble
+wxAffineMatrix2D::DoTransformPoint(const wxPoint2DDouble& src) const
+{
+    if ( IsIdentity() )
+        return src;
+
+    return wxPoint2DDouble(src.m_x * m_11 + src.m_y * m_21 + m_tx,
+                           src.m_y * m_12 + src.m_y * m_22 + m_ty);
+}
+
+// applies the matrix except for translations
+//                           | m_11  m_12   0 |
+// | src.m_x  src._my  0 | x | m_21  m_22   0 |
+//                           | m_tx  m_ty   1 |
+wxPoint2DDouble
+wxAffineMatrix2D::DoTransformDistance(const wxPoint2DDouble& src) const
+{
+    if ( IsIdentity() )
+        return src;
+
+    return wxPoint2DDouble(src.m_x * m_11 + src.m_y * m_21,
+                           src.m_y * m_12 + src.m_y * m_22);
+}
+
+bool wxAffineMatrix2D::IsIdentity() const
+{
+    return m_11 == 1 && m_12 == 0 &&
+           m_21 == 0 && m_22 == 1 &&
+           m_tx == 0 && m_ty == 0;
+}