Anti-Grain Geometry - AGG (libagg)
2.5
|
00001 //---------------------------------------------------------------------------- 00002 // Anti-Grain Geometry (AGG) - Version 2.5 00003 // A high quality rendering engine for C++ 00004 // Copyright (C) 2002-2006 Maxim Shemanarev 00005 // Contact: mcseem@antigrain.com 00006 // mcseemagg@yahoo.com 00007 // http://antigrain.com 00008 // 00009 // AGG is free software; you can redistribute it and/or 00010 // modify it under the terms of the GNU General Public License 00011 // as published by the Free Software Foundation; either version 2 00012 // of the License, or (at your option) any later version. 00013 // 00014 // AGG is distributed in the hope that it will be useful, 00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 // GNU General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU General Public License 00020 // along with AGG; if not, write to the Free Software 00021 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00022 // MA 02110-1301, USA. 00023 //---------------------------------------------------------------------------- 00024 00025 #ifndef AGG_TRANS_BILINEAR_INCLUDED 00026 #define AGG_TRANS_BILINEAR_INCLUDED 00027 00028 #include "agg_basics.h" 00029 #include "agg_simul_eq.h" 00030 00031 namespace agg 00032 { 00033 00034 //==========================================================trans_bilinear 00035 class trans_bilinear 00036 { 00037 public: 00038 //-------------------------------------------------------------------- 00039 trans_bilinear() : m_valid(false) {} 00040 00041 //-------------------------------------------------------------------- 00042 // Arbitrary quadrangle transformations 00043 trans_bilinear(const double* src, const double* dst) 00044 { 00045 quad_to_quad(src, dst); 00046 } 00047 00048 00049 //-------------------------------------------------------------------- 00050 // Direct transformations 00051 trans_bilinear(double x1, double y1, double x2, double y2, 00052 const double* quad) 00053 { 00054 rect_to_quad(x1, y1, x2, y2, quad); 00055 } 00056 00057 00058 //-------------------------------------------------------------------- 00059 // Reverse transformations 00060 trans_bilinear(const double* quad, 00061 double x1, double y1, double x2, double y2) 00062 { 00063 quad_to_rect(quad, x1, y1, x2, y2); 00064 } 00065 00066 00067 //-------------------------------------------------------------------- 00068 // Set the transformations using two arbitrary quadrangles. 00069 void quad_to_quad(const double* src, const double* dst) 00070 { 00071 double left[4][4]; 00072 double right[4][2]; 00073 00074 unsigned i; 00075 for(i = 0; i < 4; i++) 00076 { 00077 unsigned ix = i * 2; 00078 unsigned iy = ix + 1; 00079 left[i][0] = 1.0; 00080 left[i][1] = src[ix] * src[iy]; 00081 left[i][2] = src[ix]; 00082 left[i][3] = src[iy]; 00083 00084 right[i][0] = dst[ix]; 00085 right[i][1] = dst[iy]; 00086 } 00087 m_valid = simul_eq<4, 2>::solve(left, right, m_mtx); 00088 } 00089 00090 00091 //-------------------------------------------------------------------- 00092 // Set the direct transformations, i.e., rectangle -> quadrangle 00093 void rect_to_quad(double x1, double y1, double x2, double y2, 00094 const double* quad) 00095 { 00096 double src[8]; 00097 src[0] = src[6] = x1; 00098 src[2] = src[4] = x2; 00099 src[1] = src[3] = y1; 00100 src[5] = src[7] = y2; 00101 quad_to_quad(src, quad); 00102 } 00103 00104 00105 //-------------------------------------------------------------------- 00106 // Set the reverse transformations, i.e., quadrangle -> rectangle 00107 void quad_to_rect(const double* quad, 00108 double x1, double y1, double x2, double y2) 00109 { 00110 double dst[8]; 00111 dst[0] = dst[6] = x1; 00112 dst[2] = dst[4] = x2; 00113 dst[1] = dst[3] = y1; 00114 dst[5] = dst[7] = y2; 00115 quad_to_quad(quad, dst); 00116 } 00117 00118 //-------------------------------------------------------------------- 00119 // Check if the equations were solved successfully 00120 bool is_valid() const { return m_valid; } 00121 00122 //-------------------------------------------------------------------- 00123 // Transform a point (x, y) 00124 void transform(double* x, double* y) const 00125 { 00126 double tx = *x; 00127 double ty = *y; 00128 double xy = tx * ty; 00129 *x = m_mtx[0][0] + m_mtx[1][0] * xy + m_mtx[2][0] * tx + m_mtx[3][0] * ty; 00130 *y = m_mtx[0][1] + m_mtx[1][1] * xy + m_mtx[2][1] * tx + m_mtx[3][1] * ty; 00131 } 00132 00133 00134 //-------------------------------------------------------------------- 00135 class iterator_x 00136 { 00137 double inc_x; 00138 double inc_y; 00139 00140 public: 00141 double x; 00142 double y; 00143 00144 iterator_x() {} 00145 iterator_x(double tx, double ty, double step, const double m[4][2]) : 00146 inc_x(m[1][0] * step * ty + m[2][0] * step), 00147 inc_y(m[1][1] * step * ty + m[2][1] * step), 00148 x(m[0][0] + m[1][0] * tx * ty + m[2][0] * tx + m[3][0] * ty), 00149 y(m[0][1] + m[1][1] * tx * ty + m[2][1] * tx + m[3][1] * ty) 00150 { 00151 } 00152 00153 void operator ++ () 00154 { 00155 x += inc_x; 00156 y += inc_y; 00157 } 00158 }; 00159 00160 iterator_x begin(double x, double y, double step) const 00161 { 00162 return iterator_x(x, y, step, m_mtx); 00163 } 00164 00165 private: 00166 double m_mtx[4][2]; 00167 bool m_valid; 00168 }; 00169 00170 } 00171 00172 #endif