139241fe2SDarkWyrm //---------------------------------------------------------------------------- 2*e39da397SStephan Aßmus // Anti-Grain Geometry - Version 2.4 3*e39da397SStephan Aßmus // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) 439241fe2SDarkWyrm // 539241fe2SDarkWyrm // Permission to copy, use, modify, sell and distribute this software 639241fe2SDarkWyrm // is granted provided this copyright notice appears in all copies. 739241fe2SDarkWyrm // This software is provided "as is" without express or implied 839241fe2SDarkWyrm // warranty, and with no claim as to its suitability for any purpose. 939241fe2SDarkWyrm // 1039241fe2SDarkWyrm //---------------------------------------------------------------------------- 1139241fe2SDarkWyrm // Contact: mcseem@antigrain.com 1239241fe2SDarkWyrm // mcseemagg@yahoo.com 1339241fe2SDarkWyrm // http://www.antigrain.com 1439241fe2SDarkWyrm //---------------------------------------------------------------------------- 1539241fe2SDarkWyrm // 1639241fe2SDarkWyrm // Perspective 2D transformations 1739241fe2SDarkWyrm // 1839241fe2SDarkWyrm //---------------------------------------------------------------------------- 1939241fe2SDarkWyrm #ifndef AGG_TRANS_PERSPECTIVE_INCLUDED 2039241fe2SDarkWyrm #define AGG_TRANS_PERSPECTIVE_INCLUDED 2139241fe2SDarkWyrm 2239241fe2SDarkWyrm #include "agg_basics.h" 2339241fe2SDarkWyrm #include "agg_simul_eq.h" 2439241fe2SDarkWyrm 2539241fe2SDarkWyrm namespace agg 2639241fe2SDarkWyrm { 2739241fe2SDarkWyrm //=======================================================trans_perspective 2839241fe2SDarkWyrm class trans_perspective 2939241fe2SDarkWyrm { 3039241fe2SDarkWyrm public: 3139241fe2SDarkWyrm //-------------------------------------------------------------------- 3239241fe2SDarkWyrm trans_perspective() : m_valid(false) {} 3339241fe2SDarkWyrm 3439241fe2SDarkWyrm 3539241fe2SDarkWyrm //-------------------------------------------------------------------- 3639241fe2SDarkWyrm // Arbitrary quadrangle transformations 3739241fe2SDarkWyrm trans_perspective(const double* src, const double* dst) 3839241fe2SDarkWyrm { 3939241fe2SDarkWyrm quad_to_quad(src, dst); 4039241fe2SDarkWyrm } 4139241fe2SDarkWyrm 4239241fe2SDarkWyrm 4339241fe2SDarkWyrm //-------------------------------------------------------------------- 4439241fe2SDarkWyrm // Direct transformations 4539241fe2SDarkWyrm trans_perspective(double x1, double y1, double x2, double y2, 4639241fe2SDarkWyrm const double* quad) 4739241fe2SDarkWyrm { 4839241fe2SDarkWyrm rect_to_quad(x1, y1, x2, y2, quad); 4939241fe2SDarkWyrm } 5039241fe2SDarkWyrm 5139241fe2SDarkWyrm 5239241fe2SDarkWyrm //-------------------------------------------------------------------- 5339241fe2SDarkWyrm // Reverse transformations 5439241fe2SDarkWyrm trans_perspective(const double* quad, 5539241fe2SDarkWyrm double x1, double y1, double x2, double y2) 5639241fe2SDarkWyrm { 5739241fe2SDarkWyrm quad_to_rect(quad, x1, y1, x2, y2); 5839241fe2SDarkWyrm } 5939241fe2SDarkWyrm 6039241fe2SDarkWyrm 6139241fe2SDarkWyrm //-------------------------------------------------------------------- 6239241fe2SDarkWyrm // Set the transformations using two arbitrary quadrangles. 6339241fe2SDarkWyrm void quad_to_quad(const double* src, const double* dst) 6439241fe2SDarkWyrm { 6539241fe2SDarkWyrm 6639241fe2SDarkWyrm double left[8][8]; 6739241fe2SDarkWyrm double right[8][1]; 6839241fe2SDarkWyrm 6939241fe2SDarkWyrm unsigned i; 7039241fe2SDarkWyrm for (i = 0; i < 4; i++) 7139241fe2SDarkWyrm { 7239241fe2SDarkWyrm unsigned ix = i * 2; 7339241fe2SDarkWyrm unsigned iy = ix + 1; 7439241fe2SDarkWyrm 7539241fe2SDarkWyrm left[ix][0] = 1.0; 7639241fe2SDarkWyrm left[ix][1] = src[ix]; 7739241fe2SDarkWyrm left[ix][2] = src[iy]; 7839241fe2SDarkWyrm left[ix][3] = 0.0; 7939241fe2SDarkWyrm left[ix][4] = 0.0; 8039241fe2SDarkWyrm left[ix][5] = 0.0; 8139241fe2SDarkWyrm left[ix][6] = -src[ix] * dst[ix]; 8239241fe2SDarkWyrm left[ix][7] = -src[iy] * dst[ix]; 8339241fe2SDarkWyrm right[ix][0] = dst[ix]; 8439241fe2SDarkWyrm 8539241fe2SDarkWyrm left[iy][0] = 0.0; 8639241fe2SDarkWyrm left[iy][1] = 0.0; 8739241fe2SDarkWyrm left[iy][2] = 0.0; 8839241fe2SDarkWyrm left[iy][3] = 1.0; 8939241fe2SDarkWyrm left[iy][4] = src[ix]; 9039241fe2SDarkWyrm left[iy][5] = src[iy]; 9139241fe2SDarkWyrm left[iy][6] = -src[ix] * dst[iy]; 9239241fe2SDarkWyrm left[iy][7] = -src[iy] * dst[iy]; 9339241fe2SDarkWyrm right[iy][0] = dst[iy]; 9439241fe2SDarkWyrm } 9539241fe2SDarkWyrm m_valid = simul_eq<8, 1>::solve(left, right, m_mtx); 9639241fe2SDarkWyrm } 9739241fe2SDarkWyrm 9839241fe2SDarkWyrm 9939241fe2SDarkWyrm //-------------------------------------------------------------------- 10039241fe2SDarkWyrm // Set the direct transformations, i.e., rectangle -> quadrangle 10139241fe2SDarkWyrm void rect_to_quad(double x1, double y1, double x2, double y2, 10239241fe2SDarkWyrm const double* quad) 10339241fe2SDarkWyrm { 10439241fe2SDarkWyrm double src[8]; 10539241fe2SDarkWyrm src[0] = src[6] = x1; 10639241fe2SDarkWyrm src[2] = src[4] = x2; 10739241fe2SDarkWyrm src[1] = src[3] = y1; 10839241fe2SDarkWyrm src[5] = src[7] = y2; 10939241fe2SDarkWyrm quad_to_quad(src, quad); 11039241fe2SDarkWyrm } 11139241fe2SDarkWyrm 11239241fe2SDarkWyrm 11339241fe2SDarkWyrm //-------------------------------------------------------------------- 11439241fe2SDarkWyrm // Set the reverse transformations, i.e., quadrangle -> rectangle 11539241fe2SDarkWyrm void quad_to_rect(const double* quad, 11639241fe2SDarkWyrm double x1, double y1, double x2, double y2) 11739241fe2SDarkWyrm { 11839241fe2SDarkWyrm double dst[8]; 11939241fe2SDarkWyrm dst[0] = dst[6] = x1; 12039241fe2SDarkWyrm dst[2] = dst[4] = x2; 12139241fe2SDarkWyrm dst[1] = dst[3] = y1; 12239241fe2SDarkWyrm dst[5] = dst[7] = y2; 12339241fe2SDarkWyrm quad_to_quad(quad, dst); 12439241fe2SDarkWyrm } 12539241fe2SDarkWyrm 12639241fe2SDarkWyrm //-------------------------------------------------------------------- 12739241fe2SDarkWyrm // Check if the equations were solved successfully 12839241fe2SDarkWyrm bool is_valid() const { return m_valid; } 12939241fe2SDarkWyrm 13039241fe2SDarkWyrm //-------------------------------------------------------------------- 13139241fe2SDarkWyrm // Transform a point (x, y) 13239241fe2SDarkWyrm void transform(double* x, double* y) const 13339241fe2SDarkWyrm { 13439241fe2SDarkWyrm double tx = *x; 13539241fe2SDarkWyrm double ty = *y; 13639241fe2SDarkWyrm double d = 1.0 / (m_mtx[6][0] * tx + m_mtx[7][0] * ty + 1.0); 13739241fe2SDarkWyrm *x = (m_mtx[0][0] + m_mtx[1][0] * tx + m_mtx[2][0] * ty) * d; 13839241fe2SDarkWyrm *y = (m_mtx[3][0] + m_mtx[4][0] * tx + m_mtx[5][0] * ty) * d; 13939241fe2SDarkWyrm } 14039241fe2SDarkWyrm 141*e39da397SStephan Aßmus //-------------------------------------------------------------------- 142*e39da397SStephan Aßmus class iterator_x 143*e39da397SStephan Aßmus { 144*e39da397SStephan Aßmus double den; 145*e39da397SStephan Aßmus double den_step; 146*e39da397SStephan Aßmus double nom_x; 147*e39da397SStephan Aßmus double nom_x_step; 148*e39da397SStephan Aßmus double nom_y; 149*e39da397SStephan Aßmus double nom_y_step; 150*e39da397SStephan Aßmus 151*e39da397SStephan Aßmus public: 152*e39da397SStephan Aßmus double x; 153*e39da397SStephan Aßmus double y; 154*e39da397SStephan Aßmus 155*e39da397SStephan Aßmus iterator_x() {} 156*e39da397SStephan Aßmus iterator_x(double tx, double ty, double step, const double m[8][1]) : 157*e39da397SStephan Aßmus den(m[6][0] * tx + m[7][0] * ty + 1.0), 158*e39da397SStephan Aßmus den_step(m[6][0] * step), 159*e39da397SStephan Aßmus nom_x(m[0][0] + m[1][0] * tx + m[2][0] * ty), 160*e39da397SStephan Aßmus nom_x_step(m[1][0] * step), 161*e39da397SStephan Aßmus nom_y(m[3][0] + m[4][0] * tx + m[5][0] * ty), 162*e39da397SStephan Aßmus nom_y_step(m[4][0] * step), 163*e39da397SStephan Aßmus x(nom_x / den), 164*e39da397SStephan Aßmus y(nom_y / den) 165*e39da397SStephan Aßmus { 166*e39da397SStephan Aßmus } 167*e39da397SStephan Aßmus 168*e39da397SStephan Aßmus void operator ++ () 169*e39da397SStephan Aßmus { 170*e39da397SStephan Aßmus den += den_step; 171*e39da397SStephan Aßmus nom_x += nom_x_step; 172*e39da397SStephan Aßmus nom_y += nom_y_step; 173*e39da397SStephan Aßmus double d = 1.0 / den; 174*e39da397SStephan Aßmus x = nom_x * d; 175*e39da397SStephan Aßmus y = nom_y * d; 176*e39da397SStephan Aßmus } 177*e39da397SStephan Aßmus }; 178*e39da397SStephan Aßmus 179*e39da397SStephan Aßmus //-------------------------------------------------------------------- 180*e39da397SStephan Aßmus iterator_x begin(double x, double y, double step) const 181*e39da397SStephan Aßmus { 182*e39da397SStephan Aßmus return iterator_x(x, y, step, m_mtx); 183*e39da397SStephan Aßmus } 184*e39da397SStephan Aßmus 18539241fe2SDarkWyrm private: 18639241fe2SDarkWyrm double m_mtx[8][1]; 18739241fe2SDarkWyrm bool m_valid; 18839241fe2SDarkWyrm }; 18939241fe2SDarkWyrm 19039241fe2SDarkWyrm } 19139241fe2SDarkWyrm 19239241fe2SDarkWyrm #endif 193