Anti-Grain Geometry - AGG (libagg)  2.5
agg-2.5/include/agg_trans_perspective.h
Go to the documentation of this file.
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_PERSPECTIVE_INCLUDED
00026 #define AGG_TRANS_PERSPECTIVE_INCLUDED
00027 
00028 #include "agg_trans_affine.h"
00029 
00030 namespace agg
00031 {
00032     //=======================================================trans_perspective
00033     struct trans_perspective
00034     {
00035         double sx, shy, w0, shx, sy, w1, tx, ty, w2;
00036 
00037         //------------------------------------------------------- Construction
00038         // Identity matrix
00039         trans_perspective() : 
00040             sx (1), shy(0), w0(0), 
00041             shx(0), sy (1), w1(0), 
00042             tx (0), ty (0), w2(1) {}
00043 
00044         // Custom matrix
00045         trans_perspective(double v0, double v1, double v2, 
00046                           double v3, double v4, double v5,
00047                           double v6, double v7, double v8) :
00048            sx (v0), shy(v1), w0(v2), 
00049            shx(v3), sy (v4), w1(v5), 
00050            tx (v6), ty (v7), w2(v8) {}
00051 
00052         // Custom matrix from m[9]
00053         explicit trans_perspective(const double* m) :
00054            sx (m[0]), shy(m[1]), w0(m[2]), 
00055            shx(m[3]), sy (m[4]), w1(m[5]), 
00056            tx (m[6]), ty (m[7]), w2(m[8]) {}
00057 
00058         // From affine
00059         explicit trans_perspective(const trans_affine& a) : 
00060            sx (a.sx ), shy(a.shy), w0(0), 
00061            shx(a.shx), sy (a.sy ), w1(0), 
00062            tx (a.tx ), ty (a.ty ), w2(1) {}
00063 
00064         // Rectangle to quadrilateral
00065         trans_perspective(double x1, double y1, double x2, double y2, 
00066                           const double* quad);
00067 
00068         // Quadrilateral to rectangle
00069         trans_perspective(const double* quad, 
00070                           double x1, double y1, double x2, double y2);
00071 
00072         // Arbitrary quadrilateral transformations
00073         trans_perspective(const double* src, const double* dst);
00074 
00075         //-------------------------------------- Quadrilateral transformations
00076         // The arguments are double[8] that are mapped to quadrilaterals:
00077         // x1,y1, x2,y2, x3,y3, x4,y4
00078         bool quad_to_quad(const double* qs, const double* qd);
00079 
00080         bool rect_to_quad(double x1, double y1, 
00081                           double x2, double y2,
00082                           const double* q);
00083 
00084         bool quad_to_rect(const double* q,
00085                           double x1, double y1, 
00086                           double x2, double y2);
00087 
00088         // Map square (0,0,1,1) to the quadrilateral and vice versa
00089         bool square_to_quad(const double* q);
00090         bool quad_to_square(const double* q);
00091 
00092 
00093         //--------------------------------------------------------- Operations
00094         // Reset - load an identity matrix
00095         const trans_perspective& reset();
00096 
00097         // Invert matrix. Returns false in degenerate case
00098         bool invert();
00099 
00100         // Direct transformations operations
00101         const trans_perspective& translate(double x, double y);
00102         const trans_perspective& rotate(double a);
00103         const trans_perspective& scale(double s);
00104         const trans_perspective& scale(double x, double y);
00105 
00106         // Multiply the matrix by another one
00107         const trans_perspective& multiply(const trans_perspective& m);
00108 
00109         // Multiply "m" by "this" and assign the result to "this"
00110         const trans_perspective& premultiply(const trans_perspective& m);
00111 
00112         // Multiply matrix to inverse of another one
00113         const trans_perspective& multiply_inv(const trans_perspective& m);
00114 
00115         // Multiply inverse of "m" by "this" and assign the result to "this"
00116         const trans_perspective& premultiply_inv(const trans_perspective& m);
00117 
00118         // Multiply the matrix by another one
00119         const trans_perspective& multiply(const trans_affine& m);
00120 
00121         // Multiply "m" by "this" and assign the result to "this"
00122         const trans_perspective& premultiply(const trans_affine& m);
00123 
00124         // Multiply the matrix by inverse of another one
00125         const trans_perspective& multiply_inv(const trans_affine& m);
00126 
00127         // Multiply inverse of "m" by "this" and assign the result to "this"
00128         const trans_perspective& premultiply_inv(const trans_affine& m);
00129 
00130         //--------------------------------------------------------- Load/Store
00131         void store_to(double* m) const;
00132         const trans_perspective& load_from(const double* m);
00133 
00134         //---------------------------------------------------------- Operators
00135         // Multiply the matrix by another one
00136         const trans_perspective& operator *= (const trans_perspective& m)
00137         {
00138             return multiply(m);
00139         }
00140         const trans_perspective& operator *= (const trans_affine& m)
00141         {
00142             return multiply(m);
00143         }
00144 
00145         // Multiply the matrix by inverse of another one
00146         const trans_perspective& operator /= (const trans_perspective& m)
00147         {
00148             return multiply_inv(m);
00149         }
00150         const trans_perspective& operator /= (const trans_affine& m)
00151         {
00152             return multiply_inv(m);
00153         }
00154 
00155         // Multiply the matrix by another one and return
00156         // the result in a separete matrix.
00157         trans_perspective operator * (const trans_perspective& m)
00158         {
00159             return trans_perspective(*this).multiply(m);
00160         }
00161         trans_perspective operator * (const trans_affine& m)
00162         {
00163             return trans_perspective(*this).multiply(m);
00164         }
00165 
00166         // Multiply the matrix by inverse of another one 
00167         // and return the result in a separete matrix.
00168         trans_perspective operator / (const trans_perspective& m)
00169         {
00170             return trans_perspective(*this).multiply_inv(m);
00171         }
00172         trans_perspective operator / (const trans_affine& m)
00173         {
00174             return trans_perspective(*this).multiply_inv(m);
00175         }
00176 
00177         // Calculate and return the inverse matrix
00178         trans_perspective operator ~ () const
00179         {
00180             trans_perspective ret = *this;
00181             ret.invert();
00182             return ret;
00183         }
00184 
00185         // Equal operator with default epsilon
00186         bool operator == (const trans_perspective& m) const
00187         {
00188             return is_equal(m, affine_epsilon);
00189         }
00190 
00191         // Not Equal operator with default epsilon
00192         bool operator != (const trans_perspective& m) const
00193         {
00194             return !is_equal(m, affine_epsilon);
00195         }
00196 
00197         //---------------------------------------------------- Transformations
00198         // Direct transformation of x and y
00199         void transform(double* x, double* y) const;
00200 
00201         // Direct transformation of x and y, affine part only
00202         void transform_affine(double* x, double* y) const;
00203 
00204         // Direct transformation of x and y, 2x2 matrix only, no translation
00205         void transform_2x2(double* x, double* y) const;
00206 
00207         // Inverse transformation of x and y. It works slow because
00208         // it explicitly inverts the matrix on every call. For massive 
00209         // operations it's better to invert() the matrix and then use 
00210         // direct transformations. 
00211         void inverse_transform(double* x, double* y) const;
00212 
00213 
00214         //---------------------------------------------------------- Auxiliary
00215         const trans_perspective& from_affine(const trans_affine& a);
00216         double determinant() const;
00217         double determinant_reciprocal() const;
00218 
00219         bool is_valid(double epsilon = affine_epsilon) const;
00220         bool is_identity(double epsilon = affine_epsilon) const;
00221         bool is_equal(const trans_perspective& m, 
00222                       double epsilon = affine_epsilon) const;
00223 
00224         // Determine the major affine parameters. Use with caution 
00225         // considering possible degenerate cases.
00226         double scale() const;
00227         double rotation() const;
00228         void   translation(double* dx, double* dy) const;
00229         void   scaling(double* x, double* y) const;
00230         void   scaling_abs(double* x, double* y) const;
00231 
00232 
00233 
00234         //--------------------------------------------------------------------
00235         class iterator_x
00236         {
00237             double den;
00238             double den_step;
00239             double nom_x;
00240             double nom_x_step;
00241             double nom_y;
00242             double nom_y_step;
00243 
00244         public:
00245             double x;
00246             double y;
00247 
00248             iterator_x() {}
00249             iterator_x(double px, double py, double step, const trans_perspective& m) :
00250                 den(px * m.w0 + py * m.w1 + m.w2),
00251                 den_step(m.w0 * step),
00252                 nom_x(px * m.sx + py * m.shx + m.tx),
00253                 nom_x_step(step * m.sx),
00254                 nom_y(px * m.shy + py * m.sy + m.ty),
00255                 nom_y_step(step * m.shy),
00256                 x(nom_x / den),
00257                 y(nom_y / den)
00258             {}
00259 
00260             void operator ++ ()
00261             {
00262                 den   += den_step;
00263                 nom_x += nom_x_step;
00264                 nom_y += nom_y_step;
00265                 double d = 1.0 / den;
00266                 x = nom_x * d;
00267                 y = nom_y * d;
00268             }
00269         };
00270 
00271         //--------------------------------------------------------------------
00272         iterator_x begin(double x, double y, double step) const
00273         {
00274             return iterator_x(x, y, step, *this);
00275         }
00276     };
00277 
00278 
00279 
00280 
00281 
00282 
00283 
00284 
00285 
00286    
00287 
00288 
00289 
00290 
00291     //------------------------------------------------------------------------
00292     inline bool trans_perspective::square_to_quad(const double* q)
00293     {
00294         double dx = q[0] - q[2] + q[4] - q[6];
00295         double dy = q[1] - q[3] + q[5] - q[7];
00296         if(dx == 0.0 && dy == 0.0)
00297         {   
00298             // Affine case (parallelogram)
00299             //---------------
00300             sx  = q[2] - q[0];
00301             shy = q[3] - q[1];
00302             w0  = 0.0;
00303             shx = q[4] - q[2];
00304             sy  = q[5] - q[3];
00305             w1  = 0.0;
00306             tx  = q[0];
00307             ty  = q[1];
00308             w2  = 1.0;
00309         }
00310         else
00311         {
00312             double dx1 = q[2] - q[4];
00313             double dy1 = q[3] - q[5];
00314             double dx2 = q[6] - q[4];
00315             double dy2 = q[7] - q[5];
00316             double den = dx1 * dy2 - dx2 * dy1;
00317             if(den == 0.0)
00318             {
00319                 // Singular case
00320                 //---------------
00321                 sx = shy = w0 = shx = sy = w1 = tx = ty = w2 = 0.0;
00322                 return false;
00323             }
00324             // General case
00325             //---------------
00326             double u = (dx * dy2 - dy * dx2) / den;
00327             double v = (dy * dx1 - dx * dy1) / den;
00328             sx  = q[2] - q[0] + u * q[2];
00329             shy = q[3] - q[1] + u * q[3];
00330             w0  = u;
00331             shx = q[6] - q[0] + v * q[6];
00332             sy  = q[7] - q[1] + v * q[7];
00333             w1  = v;
00334             tx  = q[0];
00335             ty  = q[1];
00336             w2  = 1.0;
00337         }
00338         return true;
00339     }
00340 
00341     //------------------------------------------------------------------------
00342     inline bool trans_perspective::invert()
00343     {
00344         double d0 = sy  * w2 - w1  * ty;
00345         double d1 = w0  * ty - shy * w2;
00346         double d2 = shy * w1 - w0  * sy;
00347         double d  = sx  * d0 + shx * d1 + tx * d2;
00348         if(d == 0.0) 
00349         {
00350             sx = shy = w0 = shx = sy = w1 = tx = ty = w2 = 0.0;
00351             return false;
00352         }
00353         d = 1.0 / d;
00354         trans_perspective a = *this;
00355         sx  = d * d0;
00356         shy = d * d1;
00357         w0  = d * d2;
00358         shx = d * (a.w1 *a.tx  - a.shx*a.w2);
00359         sy  = d * (a.sx *a.w2  - a.w0 *a.tx);
00360         w1  = d * (a.w0 *a.shx - a.sx *a.w1);
00361         tx  = d * (a.shx*a.ty  - a.sy *a.tx);
00362         ty  = d * (a.shy*a.tx  - a.sx *a.ty);
00363         w2  = d * (a.sx *a.sy  - a.shy*a.shx);
00364         return true;
00365     }
00366 
00367     //------------------------------------------------------------------------
00368     inline bool trans_perspective::quad_to_square(const double* q)
00369     {
00370         if(!square_to_quad(q)) return false;
00371         invert();
00372         return true;
00373     }
00374 
00375     //------------------------------------------------------------------------
00376     inline bool trans_perspective::quad_to_quad(const double* qs, 
00377                                                 const double* qd)
00378     {
00379         trans_perspective p;
00380         if(!  quad_to_square(qs)) return false;
00381         if(!p.square_to_quad(qd)) return false;
00382         multiply(p);
00383         return true;
00384     }
00385 
00386     //------------------------------------------------------------------------
00387     inline bool trans_perspective::rect_to_quad(double x1, double y1, 
00388                                                 double x2, double y2,
00389                                                 const double* q)
00390     {
00391         double r[8];
00392         r[0] = r[6] = x1;
00393         r[2] = r[4] = x2;
00394         r[1] = r[3] = y1;
00395         r[5] = r[7] = y2;
00396         return quad_to_quad(r, q);
00397     }
00398 
00399     //------------------------------------------------------------------------
00400     inline bool trans_perspective::quad_to_rect(const double* q,
00401                                                 double x1, double y1, 
00402                                                 double x2, double y2)
00403     {
00404         double r[8];
00405         r[0] = r[6] = x1;
00406         r[2] = r[4] = x2;
00407         r[1] = r[3] = y1;
00408         r[5] = r[7] = y2;
00409         return quad_to_quad(q, r);
00410     }
00411 
00412     //------------------------------------------------------------------------
00413     inline trans_perspective::trans_perspective(double x1, double y1, 
00414                                                 double x2, double y2, 
00415                                                 const double* quad)
00416     {
00417         rect_to_quad(x1, y1, x2, y2, quad);
00418     }
00419 
00420     //------------------------------------------------------------------------
00421     inline trans_perspective::trans_perspective(const double* quad, 
00422                                                 double x1, double y1, 
00423                                                 double x2, double y2)
00424     {
00425         quad_to_rect(quad, x1, y1, x2, y2);
00426     }
00427 
00428     //------------------------------------------------------------------------
00429     inline trans_perspective::trans_perspective(const double* src, 
00430                                                 const double* dst) 
00431     {
00432         quad_to_quad(src, dst);
00433     }
00434 
00435     //------------------------------------------------------------------------
00436     inline const trans_perspective& trans_perspective::reset()
00437     {
00438         sx  = 1; shy = 0; w0 = 0; 
00439         shx = 0; sy  = 1; w1 = 0;
00440         tx  = 0; ty  = 0; w2 = 1;
00441         return *this;
00442     }
00443 
00444     //------------------------------------------------------------------------
00445     inline const trans_perspective& 
00446     trans_perspective::multiply(const trans_perspective& a)
00447     {
00448         trans_perspective b = *this;
00449         sx  = a.sx *b.sx  + a.shx*b.shy + a.tx*b.w0;
00450         shx = a.sx *b.shx + a.shx*b.sy  + a.tx*b.w1;
00451         tx  = a.sx *b.tx  + a.shx*b.ty  + a.tx*b.w2;
00452         shy = a.shy*b.sx  + a.sy *b.shy + a.ty*b.w0;
00453         sy  = a.shy*b.shx + a.sy *b.sy  + a.ty*b.w1;
00454         ty  = a.shy*b.tx  + a.sy *b.ty  + a.ty*b.w2;
00455         w0  = a.w0 *b.sx  + a.w1 *b.shy + a.w2*b.w0;
00456         w1  = a.w0 *b.shx + a.w1 *b.sy  + a.w2*b.w1;
00457         w2  = a.w0 *b.tx  + a.w1 *b.ty  + a.w2*b.w2;
00458         return *this;
00459     }
00460 
00461     //------------------------------------------------------------------------
00462     inline const trans_perspective& 
00463     trans_perspective::multiply(const trans_affine& a)
00464     {
00465         trans_perspective b = *this;
00466         sx  = a.sx *b.sx  + a.shx*b.shy + a.tx*b.w0;
00467         shx = a.sx *b.shx + a.shx*b.sy  + a.tx*b.w1;
00468         tx  = a.sx *b.tx  + a.shx*b.ty  + a.tx*b.w2;
00469         shy = a.shy*b.sx  + a.sy *b.shy + a.ty*b.w0;
00470         sy  = a.shy*b.shx + a.sy *b.sy  + a.ty*b.w1;
00471         ty  = a.shy*b.tx  + a.sy *b.ty  + a.ty*b.w2;
00472         return *this;
00473     }
00474 
00475     //------------------------------------------------------------------------
00476     inline const trans_perspective& 
00477     trans_perspective::premultiply(const trans_perspective& b)
00478     {
00479         trans_perspective a = *this;
00480         sx  = a.sx *b.sx  + a.shx*b.shy + a.tx*b.w0;
00481         shx = a.sx *b.shx + a.shx*b.sy  + a.tx*b.w1;
00482         tx  = a.sx *b.tx  + a.shx*b.ty  + a.tx*b.w2;
00483         shy = a.shy*b.sx  + a.sy *b.shy + a.ty*b.w0;
00484         sy  = a.shy*b.shx + a.sy *b.sy  + a.ty*b.w1;
00485         ty  = a.shy*b.tx  + a.sy *b.ty  + a.ty*b.w2;
00486         w0  = a.w0 *b.sx  + a.w1 *b.shy + a.w2*b.w0;
00487         w1  = a.w0 *b.shx + a.w1 *b.sy  + a.w2*b.w1;
00488         w2  = a.w0 *b.tx  + a.w1 *b.ty  + a.w2*b.w2;
00489         return *this;
00490     }
00491 
00492     //------------------------------------------------------------------------
00493     inline const trans_perspective& 
00494     trans_perspective::premultiply(const trans_affine& b)
00495     {
00496         trans_perspective a = *this;
00497         sx  = a.sx *b.sx  + a.shx*b.shy;
00498         shx = a.sx *b.shx + a.shx*b.sy;
00499         tx  = a.sx *b.tx  + a.shx*b.ty  + a.tx;
00500         shy = a.shy*b.sx  + a.sy *b.shy;
00501         sy  = a.shy*b.shx + a.sy *b.sy;
00502         ty  = a.shy*b.tx  + a.sy *b.ty  + a.ty;
00503         w0  = a.w0 *b.sx  + a.w1 *b.shy;
00504         w1  = a.w0 *b.shx + a.w1 *b.sy;
00505         w2  = a.w0 *b.tx  + a.w1 *b.ty  + a.w2;
00506         return *this;
00507     }
00508 
00509     //------------------------------------------------------------------------
00510     const trans_perspective& 
00511     trans_perspective::multiply_inv(const trans_perspective& m)
00512     {
00513         trans_perspective t = m;
00514         t.invert();
00515         return multiply(t);
00516     }
00517 
00518     //------------------------------------------------------------------------
00519     const trans_perspective&
00520     trans_perspective::multiply_inv(const trans_affine& m)
00521     {
00522         trans_affine t = m;
00523         t.invert();
00524         return multiply(t);
00525     }
00526 
00527     //------------------------------------------------------------------------
00528     const trans_perspective&
00529     trans_perspective::premultiply_inv(const trans_perspective& m)
00530     {
00531         trans_perspective t = m;
00532         t.invert();
00533         return *this = t.multiply(*this);
00534     }
00535 
00536     //------------------------------------------------------------------------
00537     const trans_perspective&
00538     trans_perspective::premultiply_inv(const trans_affine& m)
00539     {
00540         trans_perspective t(m);
00541         t.invert();
00542         return *this = t.multiply(*this);
00543     }
00544 
00545     //------------------------------------------------------------------------
00546     inline const trans_perspective& 
00547     trans_perspective::translate(double x, double y)
00548     {
00549         tx += x;
00550         ty += y;
00551         return *this;
00552     }
00553 
00554     //------------------------------------------------------------------------
00555     inline const trans_perspective& trans_perspective::rotate(double a)
00556     {
00557         multiply(trans_affine_rotation(a));
00558         return *this;
00559     }
00560 
00561     //------------------------------------------------------------------------
00562     inline const trans_perspective& trans_perspective::scale(double s)
00563     {
00564         multiply(trans_affine_scaling(s));
00565         return *this;
00566     }
00567 
00568     //------------------------------------------------------------------------
00569     inline const trans_perspective& trans_perspective::scale(double x, double y)
00570     {
00571         multiply(trans_affine_scaling(x, y));
00572         return *this;
00573     }
00574 
00575     //------------------------------------------------------------------------
00576     inline void trans_perspective::transform(double* px, double* py) const
00577     {
00578         double x = *px;
00579         double y = *py;
00580         double m = 1.0 / (x*w0 + y*w1 + w2);
00581         *px = m * (x*sx  + y*shx + tx);
00582         *py = m * (x*shy + y*sy  + ty);
00583     }
00584 
00585     //------------------------------------------------------------------------
00586     inline void trans_perspective::transform_affine(double* x, double* y) const
00587     {
00588         double tmp = *x;
00589         *x = tmp * sx  + *y * shx + tx;
00590         *y = tmp * shy + *y * sy  + ty;
00591     }
00592 
00593     //------------------------------------------------------------------------
00594     inline void trans_perspective::transform_2x2(double* x, double* y) const
00595     {
00596         double tmp = *x;
00597         *x = tmp * sx  + *y * shx;
00598         *y = tmp * shy + *y * sy;
00599     }
00600 
00601     //------------------------------------------------------------------------
00602     inline void trans_perspective::inverse_transform(double* x, double* y) const
00603     {
00604         trans_perspective t(*this);
00605         if(t.invert()) t.transform(x, y);
00606     }
00607 
00608     //------------------------------------------------------------------------
00609     inline void trans_perspective::store_to(double* m) const
00610     {
00611         *m++ = sx;  *m++ = shy; *m++ = w0; 
00612         *m++ = shx; *m++ = sy;  *m++ = w1;
00613         *m++ = tx;  *m++ = ty;  *m++ = w2;
00614     }
00615 
00616     //------------------------------------------------------------------------
00617     inline const trans_perspective& trans_perspective::load_from(const double* m)
00618     {
00619         sx  = *m++; shy = *m++; w0 = *m++; 
00620         shx = *m++; sy  = *m++; w1 = *m++;
00621         tx  = *m++; ty  = *m++; w2 = *m++;
00622         return *this;
00623     }
00624 
00625     //------------------------------------------------------------------------
00626     inline const trans_perspective& 
00627     trans_perspective::from_affine(const trans_affine& a)
00628     {
00629         sx  = a.sx;  shy = a.shy; w0 = 0; 
00630         shx = a.shx; sy  = a.sy;  w1 = 0;
00631         tx  = a.tx;  ty  = a.ty;  w2 = 1;
00632         return *this;
00633     }
00634 
00635     //------------------------------------------------------------------------
00636     inline double trans_perspective::determinant() const
00637     {
00638         return sx  * (sy  * w2 - ty  * w1) +
00639                shx * (ty  * w0 - shy * w2) +
00640                tx  * (shy * w1 - sy  * w0);
00641     }
00642   
00643     //------------------------------------------------------------------------
00644     inline double trans_perspective::determinant_reciprocal() const
00645     {
00646         return 1.0 / determinant();
00647     }
00648 
00649     //------------------------------------------------------------------------
00650     inline bool trans_perspective::is_valid(double epsilon) const
00651     {
00652         return fabs(sx) > epsilon && fabs(sy) > epsilon && fabs(w2) > epsilon;
00653     }
00654 
00655     //------------------------------------------------------------------------
00656     inline bool trans_perspective::is_identity(double epsilon) const
00657     {
00658         return is_equal_eps(sx,  1.0, epsilon) &&
00659                is_equal_eps(shy, 0.0, epsilon) &&
00660                is_equal_eps(w0,  0.0, epsilon) &&
00661                is_equal_eps(shx, 0.0, epsilon) && 
00662                is_equal_eps(sy,  1.0, epsilon) &&
00663                is_equal_eps(w1,  0.0, epsilon) &&
00664                is_equal_eps(tx,  0.0, epsilon) &&
00665                is_equal_eps(ty,  0.0, epsilon) &&
00666                is_equal_eps(w2,  1.0, epsilon);
00667     }
00668 
00669     //------------------------------------------------------------------------
00670     inline bool trans_perspective::is_equal(const trans_perspective& m, 
00671                                             double epsilon) const
00672     {
00673         return is_equal_eps(sx,  m.sx,  epsilon) &&
00674                is_equal_eps(shy, m.shy, epsilon) &&
00675                is_equal_eps(w0,  m.w0,  epsilon) &&
00676                is_equal_eps(shx, m.shx, epsilon) && 
00677                is_equal_eps(sy,  m.sy,  epsilon) &&
00678                is_equal_eps(w1,  m.w1,  epsilon) &&
00679                is_equal_eps(tx,  m.tx,  epsilon) &&
00680                is_equal_eps(ty,  m.ty,  epsilon) &&
00681                is_equal_eps(w2,  m.w2,  epsilon);
00682     }
00683 
00684     //------------------------------------------------------------------------
00685     inline double trans_perspective::scale() const
00686     {
00687         double x = 0.707106781 * sx  + 0.707106781 * shx;
00688         double y = 0.707106781 * shy + 0.707106781 * sy;
00689         return sqrt(x*x + y*y);
00690     }
00691 
00692     //------------------------------------------------------------------------
00693     inline double trans_perspective::rotation() const
00694     {
00695         double x1 = 0.0;
00696         double y1 = 0.0;
00697         double x2 = 1.0;
00698         double y2 = 0.0;
00699         transform(&x1, &y1);
00700         transform(&x2, &y2);
00701         return atan2(y2-y1, x2-x1);
00702     }
00703 
00704     //------------------------------------------------------------------------
00705     void trans_perspective::translation(double* dx, double* dy) const
00706     {
00707         *dx = tx;
00708         *dy = ty;
00709     }
00710 
00711     //------------------------------------------------------------------------
00712     void trans_perspective::scaling(double* x, double* y) const
00713     {
00714         double x1 = 0.0;
00715         double y1 = 0.0;
00716         double x2 = 1.0;
00717         double y2 = 1.0;
00718         trans_perspective t(*this);
00719         t *= trans_affine_rotation(-rotation());
00720         t.transform(&x1, &y1);
00721         t.transform(&x2, &y2);
00722         *x = x2 - x1;
00723         *y = y2 - y1;
00724     }
00725 
00726     //------------------------------------------------------------------------
00727     void trans_perspective::scaling_abs(double* x, double* y) const
00728     {
00729         *x = sqrt(sx  * sx  + shx * shx);
00730         *y = sqrt(shy * shy + sy  * sy);
00731     }
00732 
00733 
00734 }
00735 
00736 #endif
00737 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines