summaryrefslogtreecommitdiff
path: root/agg/inc/agg_trans_perspective.h
diff options
context:
space:
mode:
Diffstat (limited to 'agg/inc/agg_trans_perspective.h')
-rwxr-xr-xagg/inc/agg_trans_perspective.h192
1 files changed, 192 insertions, 0 deletions
diff --git a/agg/inc/agg_trans_perspective.h b/agg/inc/agg_trans_perspective.h
new file mode 100755
index 000000000000..a127c9095ad2
--- /dev/null
+++ b/agg/inc/agg_trans_perspective.h
@@ -0,0 +1,192 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.3
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// Perspective 2D transformations
+//
+//----------------------------------------------------------------------------
+#ifndef AGG_TRANS_PERSPECTIVE_INCLUDED
+#define AGG_TRANS_PERSPECTIVE_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_simul_eq.h"
+
+namespace agg
+{
+ //=======================================================trans_perspective
+ class trans_perspective
+ {
+ public:
+ //--------------------------------------------------------------------
+ trans_perspective() : m_valid(false) {}
+
+
+ //--------------------------------------------------------------------
+ // Arbitrary quadrangle transformations
+ trans_perspective(const double* src, const double* dst)
+ {
+ quad_to_quad(src, dst);
+ }
+
+
+ //--------------------------------------------------------------------
+ // Direct transformations
+ trans_perspective(double x1, double y1, double x2, double y2,
+ const double* quad)
+ {
+ rect_to_quad(x1, y1, x2, y2, quad);
+ }
+
+
+ //--------------------------------------------------------------------
+ // Reverse transformations
+ trans_perspective(const double* quad,
+ double x1, double y1, double x2, double y2)
+ {
+ quad_to_rect(quad, x1, y1, x2, y2);
+ }
+
+
+ //--------------------------------------------------------------------
+ // Set the transformations using two arbitrary quadrangles.
+ void quad_to_quad(const double* src, const double* dst)
+ {
+
+ double left[8][8];
+ double right[8][1];
+
+ unsigned i;
+ for (i = 0; i < 4; i++)
+ {
+ unsigned ix = i * 2;
+ unsigned iy = ix + 1;
+
+ left[ix][0] = 1.0;
+ left[ix][1] = src[ix];
+ left[ix][2] = src[iy];
+ left[ix][3] = 0.0;
+ left[ix][4] = 0.0;
+ left[ix][5] = 0.0;
+ left[ix][6] = -src[ix] * dst[ix];
+ left[ix][7] = -src[iy] * dst[ix];
+ right[ix][0] = dst[ix];
+
+ left[iy][0] = 0.0;
+ left[iy][1] = 0.0;
+ left[iy][2] = 0.0;
+ left[iy][3] = 1.0;
+ left[iy][4] = src[ix];
+ left[iy][5] = src[iy];
+ left[iy][6] = -src[ix] * dst[iy];
+ left[iy][7] = -src[iy] * dst[iy];
+ right[iy][0] = dst[iy];
+ }
+ m_valid = simul_eq<8, 1>::solve(left, right, m_mtx);
+ }
+
+
+ //--------------------------------------------------------------------
+ // Set the direct transformations, i.e., rectangle -> quadrangle
+ void rect_to_quad(double x1, double y1, double x2, double y2,
+ const double* quad)
+ {
+ double src[8];
+ src[0] = src[6] = x1;
+ src[2] = src[4] = x2;
+ src[1] = src[3] = y1;
+ src[5] = src[7] = y2;
+ quad_to_quad(src, quad);
+ }
+
+
+ //--------------------------------------------------------------------
+ // Set the reverse transformations, i.e., quadrangle -> rectangle
+ void quad_to_rect(const double* quad,
+ double x1, double y1, double x2, double y2)
+ {
+ double dst[8];
+ dst[0] = dst[6] = x1;
+ dst[2] = dst[4] = x2;
+ dst[1] = dst[3] = y1;
+ dst[5] = dst[7] = y2;
+ quad_to_quad(quad, dst);
+ }
+
+ //--------------------------------------------------------------------
+ // Check if the equations were solved successfully
+ bool is_valid() const { return m_valid; }
+
+ //--------------------------------------------------------------------
+ // Transform a point (x, y)
+ void transform(double* x, double* y) const
+ {
+ double tx = *x;
+ double ty = *y;
+ double d = 1.0 / (m_mtx[6][0] * tx + m_mtx[7][0] * ty + 1.0);
+ *x = (m_mtx[0][0] + m_mtx[1][0] * tx + m_mtx[2][0] * ty) * d;
+ *y = (m_mtx[3][0] + m_mtx[4][0] * tx + m_mtx[5][0] * ty) * d;
+ }
+
+ //--------------------------------------------------------------------
+ class iterator_x
+ {
+ double den;
+ double den_step;
+ double nom_x;
+ double nom_x_step;
+ double nom_y;
+ double nom_y_step;
+
+ public:
+ double x;
+ double y;
+
+ iterator_x() {}
+ iterator_x(double tx, double ty, double step, const double m[8][1]) :
+ den(m[6][0] * tx + m[7][0] * ty + 1.0),
+ den_step(m[6][0] * step),
+ nom_x(m[0][0] + m[1][0] * tx + m[2][0] * ty),
+ nom_x_step(m[1][0] * step),
+ nom_y(m[3][0] + m[4][0] * tx + m[5][0] * ty),
+ nom_y_step(m[4][0] * step),
+ x(nom_x / den),
+ y(nom_y / den)
+ {
+ }
+
+ void operator ++ ()
+ {
+ den += den_step;
+ nom_x += nom_x_step;
+ nom_y += nom_y_step;
+ double d = 1.0 / den;
+ x = nom_x * d;
+ y = nom_y * d;
+ }
+ };
+
+ //--------------------------------------------------------------------
+ iterator_x begin(double x, double y, double step) const
+ {
+ return iterator_x(x, y, step, m_mtx);
+ }
+
+ private:
+ double m_mtx[8][1];
+ bool m_valid;
+ };
+
+}
+
+#endif