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_SPAN_INTERPOLATOR_PERSP_INCLUDED 00026 #define AGG_SPAN_INTERPOLATOR_PERSP_INCLUDED 00027 00028 #include "agg_trans_perspective.h" 00029 #include "agg_dda_line.h" 00030 00031 namespace agg 00032 { 00033 00034 00035 00036 //===========================================span_interpolator_persp_exact 00037 template<unsigned SubpixelShift = 8> 00038 class span_interpolator_persp_exact 00039 { 00040 public: 00041 typedef trans_perspective trans_type; 00042 typedef trans_perspective::iterator_x iterator_type; 00043 enum subpixel_scale_e 00044 { 00045 subpixel_shift = SubpixelShift, 00046 subpixel_scale = 1 << subpixel_shift 00047 }; 00048 00049 //-------------------------------------------------------------------- 00050 span_interpolator_persp_exact() {} 00051 00052 //-------------------------------------------------------------------- 00053 // Arbitrary quadrangle transformations 00054 span_interpolator_persp_exact(const double* src, const double* dst) 00055 { 00056 quad_to_quad(src, dst); 00057 } 00058 00059 //-------------------------------------------------------------------- 00060 // Direct transformations 00061 span_interpolator_persp_exact(double x1, double y1, 00062 double x2, double y2, 00063 const double* quad) 00064 { 00065 rect_to_quad(x1, y1, x2, y2, quad); 00066 } 00067 00068 //-------------------------------------------------------------------- 00069 // Reverse transformations 00070 span_interpolator_persp_exact(const double* quad, 00071 double x1, double y1, 00072 double x2, double y2) 00073 { 00074 quad_to_rect(quad, x1, y1, x2, y2); 00075 } 00076 00077 //-------------------------------------------------------------------- 00078 // Set the transformations using two arbitrary quadrangles. 00079 void quad_to_quad(const double* src, const double* dst) 00080 { 00081 m_trans_dir.quad_to_quad(src, dst); 00082 m_trans_inv.quad_to_quad(dst, src); 00083 } 00084 00085 //-------------------------------------------------------------------- 00086 // Set the direct transformations, i.e., rectangle -> quadrangle 00087 void rect_to_quad(double x1, double y1, double x2, double y2, 00088 const double* quad) 00089 { 00090 double src[8]; 00091 src[0] = src[6] = x1; 00092 src[2] = src[4] = x2; 00093 src[1] = src[3] = y1; 00094 src[5] = src[7] = y2; 00095 quad_to_quad(src, quad); 00096 } 00097 00098 00099 //-------------------------------------------------------------------- 00100 // Set the reverse transformations, i.e., quadrangle -> rectangle 00101 void quad_to_rect(const double* quad, 00102 double x1, double y1, double x2, double y2) 00103 { 00104 double dst[8]; 00105 dst[0] = dst[6] = x1; 00106 dst[2] = dst[4] = x2; 00107 dst[1] = dst[3] = y1; 00108 dst[5] = dst[7] = y2; 00109 quad_to_quad(quad, dst); 00110 } 00111 00112 //-------------------------------------------------------------------- 00113 // Check if the equations were solved successfully 00114 bool is_valid() const { return m_trans_dir.is_valid(); } 00115 00116 //---------------------------------------------------------------- 00117 void begin(double x, double y, unsigned len) 00118 { 00119 m_iterator = m_trans_dir.begin(x, y, 1.0); 00120 double xt = m_iterator.x; 00121 double yt = m_iterator.y; 00122 00123 double dx; 00124 double dy; 00125 const double delta = 1/double(subpixel_scale); 00126 dx = xt + delta; 00127 dy = yt; 00128 m_trans_inv.transform(&dx, &dy); 00129 dx -= x; 00130 dy -= y; 00131 int sx1 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift; 00132 dx = xt; 00133 dy = yt + delta; 00134 m_trans_inv.transform(&dx, &dy); 00135 dx -= x; 00136 dy -= y; 00137 int sy1 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift; 00138 00139 x += len; 00140 xt = x; 00141 yt = y; 00142 m_trans_dir.transform(&xt, &yt); 00143 00144 dx = xt + delta; 00145 dy = yt; 00146 m_trans_inv.transform(&dx, &dy); 00147 dx -= x; 00148 dy -= y; 00149 int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift; 00150 dx = xt; 00151 dy = yt + delta; 00152 m_trans_inv.transform(&dx, &dy); 00153 dx -= x; 00154 dy -= y; 00155 int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift; 00156 00157 m_scale_x = dda2_line_interpolator(sx1, sx2, len); 00158 m_scale_y = dda2_line_interpolator(sy1, sy2, len); 00159 } 00160 00161 00162 //---------------------------------------------------------------- 00163 void resynchronize(double xe, double ye, unsigned len) 00164 { 00165 // Assume x1,y1 are equal to the ones at the previous end point 00166 int sx1 = m_scale_x.y(); 00167 int sy1 = m_scale_y.y(); 00168 00169 // Calculate transformed coordinates at x2,y2 00170 double xt = xe; 00171 double yt = ye; 00172 m_trans_dir.transform(&xt, &yt); 00173 00174 const double delta = 1/double(subpixel_scale); 00175 double dx; 00176 double dy; 00177 00178 // Calculate scale by X at x2,y2 00179 dx = xt + delta; 00180 dy = yt; 00181 m_trans_inv.transform(&dx, &dy); 00182 dx -= xe; 00183 dy -= ye; 00184 int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift; 00185 00186 // Calculate scale by Y at x2,y2 00187 dx = xt; 00188 dy = yt + delta; 00189 m_trans_inv.transform(&dx, &dy); 00190 dx -= xe; 00191 dy -= ye; 00192 int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift; 00193 00194 // Initialize the interpolators 00195 m_scale_x = dda2_line_interpolator(sx1, sx2, len); 00196 m_scale_y = dda2_line_interpolator(sy1, sy2, len); 00197 } 00198 00199 00200 00201 //---------------------------------------------------------------- 00202 void operator++() 00203 { 00204 ++m_iterator; 00205 ++m_scale_x; 00206 ++m_scale_y; 00207 } 00208 00209 //---------------------------------------------------------------- 00210 void coordinates(int* x, int* y) const 00211 { 00212 *x = iround(m_iterator.x * subpixel_scale); 00213 *y = iround(m_iterator.y * subpixel_scale); 00214 } 00215 00216 //---------------------------------------------------------------- 00217 void local_scale(int* x, int* y) 00218 { 00219 *x = m_scale_x.y(); 00220 *y = m_scale_y.y(); 00221 } 00222 00223 //---------------------------------------------------------------- 00224 void transform(double* x, double* y) const 00225 { 00226 m_trans_dir.transform(x, y); 00227 } 00228 00229 private: 00230 trans_type m_trans_dir; 00231 trans_type m_trans_inv; 00232 iterator_type m_iterator; 00233 dda2_line_interpolator m_scale_x; 00234 dda2_line_interpolator m_scale_y; 00235 }; 00236 00237 00238 00239 00240 00241 00242 00243 00244 00245 00246 00247 //============================================span_interpolator_persp_lerp 00248 template<unsigned SubpixelShift = 8> 00249 class span_interpolator_persp_lerp 00250 { 00251 public: 00252 typedef trans_perspective trans_type; 00253 enum subpixel_scale_e 00254 { 00255 subpixel_shift = SubpixelShift, 00256 subpixel_scale = 1 << subpixel_shift 00257 }; 00258 00259 //-------------------------------------------------------------------- 00260 span_interpolator_persp_lerp() {} 00261 00262 //-------------------------------------------------------------------- 00263 // Arbitrary quadrangle transformations 00264 span_interpolator_persp_lerp(const double* src, const double* dst) 00265 { 00266 quad_to_quad(src, dst); 00267 } 00268 00269 //-------------------------------------------------------------------- 00270 // Direct transformations 00271 span_interpolator_persp_lerp(double x1, double y1, 00272 double x2, double y2, 00273 const double* quad) 00274 { 00275 rect_to_quad(x1, y1, x2, y2, quad); 00276 } 00277 00278 //-------------------------------------------------------------------- 00279 // Reverse transformations 00280 span_interpolator_persp_lerp(const double* quad, 00281 double x1, double y1, 00282 double x2, double y2) 00283 { 00284 quad_to_rect(quad, x1, y1, x2, y2); 00285 } 00286 00287 //-------------------------------------------------------------------- 00288 // Set the transformations using two arbitrary quadrangles. 00289 void quad_to_quad(const double* src, const double* dst) 00290 { 00291 m_trans_dir.quad_to_quad(src, dst); 00292 m_trans_inv.quad_to_quad(dst, src); 00293 } 00294 00295 //-------------------------------------------------------------------- 00296 // Set the direct transformations, i.e., rectangle -> quadrangle 00297 void rect_to_quad(double x1, double y1, double x2, double y2, 00298 const double* quad) 00299 { 00300 double src[8]; 00301 src[0] = src[6] = x1; 00302 src[2] = src[4] = x2; 00303 src[1] = src[3] = y1; 00304 src[5] = src[7] = y2; 00305 quad_to_quad(src, quad); 00306 } 00307 00308 00309 //-------------------------------------------------------------------- 00310 // Set the reverse transformations, i.e., quadrangle -> rectangle 00311 void quad_to_rect(const double* quad, 00312 double x1, double y1, double x2, double y2) 00313 { 00314 double dst[8]; 00315 dst[0] = dst[6] = x1; 00316 dst[2] = dst[4] = x2; 00317 dst[1] = dst[3] = y1; 00318 dst[5] = dst[7] = y2; 00319 quad_to_quad(quad, dst); 00320 } 00321 00322 //-------------------------------------------------------------------- 00323 // Check if the equations were solved successfully 00324 bool is_valid() const { return m_trans_dir.is_valid(); } 00325 00326 //---------------------------------------------------------------- 00327 void begin(double x, double y, unsigned len) 00328 { 00329 // Calculate transformed coordinates at x1,y1 00330 double xt = x; 00331 double yt = y; 00332 m_trans_dir.transform(&xt, &yt); 00333 int x1 = iround(xt * subpixel_scale); 00334 int y1 = iround(yt * subpixel_scale); 00335 00336 double dx; 00337 double dy; 00338 const double delta = 1/double(subpixel_scale); 00339 00340 // Calculate scale by X at x1,y1 00341 dx = xt + delta; 00342 dy = yt; 00343 m_trans_inv.transform(&dx, &dy); 00344 dx -= x; 00345 dy -= y; 00346 int sx1 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift; 00347 00348 // Calculate scale by Y at x1,y1 00349 dx = xt; 00350 dy = yt + delta; 00351 m_trans_inv.transform(&dx, &dy); 00352 dx -= x; 00353 dy -= y; 00354 int sy1 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift; 00355 00356 // Calculate transformed coordinates at x2,y2 00357 x += len; 00358 xt = x; 00359 yt = y; 00360 m_trans_dir.transform(&xt, &yt); 00361 int x2 = iround(xt * subpixel_scale); 00362 int y2 = iround(yt * subpixel_scale); 00363 00364 // Calculate scale by X at x2,y2 00365 dx = xt + delta; 00366 dy = yt; 00367 m_trans_inv.transform(&dx, &dy); 00368 dx -= x; 00369 dy -= y; 00370 int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift; 00371 00372 // Calculate scale by Y at x2,y2 00373 dx = xt; 00374 dy = yt + delta; 00375 m_trans_inv.transform(&dx, &dy); 00376 dx -= x; 00377 dy -= y; 00378 int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift; 00379 00380 // Initialize the interpolators 00381 m_coord_x = dda2_line_interpolator(x1, x2, len); 00382 m_coord_y = dda2_line_interpolator(y1, y2, len); 00383 m_scale_x = dda2_line_interpolator(sx1, sx2, len); 00384 m_scale_y = dda2_line_interpolator(sy1, sy2, len); 00385 } 00386 00387 00388 //---------------------------------------------------------------- 00389 void resynchronize(double xe, double ye, unsigned len) 00390 { 00391 // Assume x1,y1 are equal to the ones at the previous end point 00392 int x1 = m_coord_x.y(); 00393 int y1 = m_coord_y.y(); 00394 int sx1 = m_scale_x.y(); 00395 int sy1 = m_scale_y.y(); 00396 00397 // Calculate transformed coordinates at x2,y2 00398 double xt = xe; 00399 double yt = ye; 00400 m_trans_dir.transform(&xt, &yt); 00401 int x2 = iround(xt * subpixel_scale); 00402 int y2 = iround(yt * subpixel_scale); 00403 00404 const double delta = 1/double(subpixel_scale); 00405 double dx; 00406 double dy; 00407 00408 // Calculate scale by X at x2,y2 00409 dx = xt + delta; 00410 dy = yt; 00411 m_trans_inv.transform(&dx, &dy); 00412 dx -= xe; 00413 dy -= ye; 00414 int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift; 00415 00416 // Calculate scale by Y at x2,y2 00417 dx = xt; 00418 dy = yt + delta; 00419 m_trans_inv.transform(&dx, &dy); 00420 dx -= xe; 00421 dy -= ye; 00422 int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift; 00423 00424 // Initialize the interpolators 00425 m_coord_x = dda2_line_interpolator(x1, x2, len); 00426 m_coord_y = dda2_line_interpolator(y1, y2, len); 00427 m_scale_x = dda2_line_interpolator(sx1, sx2, len); 00428 m_scale_y = dda2_line_interpolator(sy1, sy2, len); 00429 } 00430 00431 00432 //---------------------------------------------------------------- 00433 void operator++() 00434 { 00435 ++m_coord_x; 00436 ++m_coord_y; 00437 ++m_scale_x; 00438 ++m_scale_y; 00439 } 00440 00441 //---------------------------------------------------------------- 00442 void coordinates(int* x, int* y) const 00443 { 00444 *x = m_coord_x.y(); 00445 *y = m_coord_y.y(); 00446 } 00447 00448 //---------------------------------------------------------------- 00449 void local_scale(int* x, int* y) 00450 { 00451 *x = m_scale_x.y(); 00452 *y = m_scale_y.y(); 00453 } 00454 00455 //---------------------------------------------------------------- 00456 void transform(double* x, double* y) const 00457 { 00458 m_trans_dir.transform(x, y); 00459 } 00460 00461 private: 00462 trans_type m_trans_dir; 00463 trans_type m_trans_inv; 00464 dda2_line_interpolator m_coord_x; 00465 dda2_line_interpolator m_coord_y; 00466 dda2_line_interpolator m_scale_x; 00467 dda2_line_interpolator m_scale_y; 00468 }; 00469 00470 } 00471 00472 #endif