summaryrefslogtreecommitdiff
path: root/agg/inc/agg_trans_affine.h
diff options
context:
space:
mode:
Diffstat (limited to 'agg/inc/agg_trans_affine.h')
-rwxr-xr-xagg/inc/agg_trans_affine.h344
1 files changed, 0 insertions, 344 deletions
diff --git a/agg/inc/agg_trans_affine.h b/agg/inc/agg_trans_affine.h
deleted file mode 100755
index 5a4098f904de..000000000000
--- a/agg/inc/agg_trans_affine.h
+++ /dev/null
@@ -1,344 +0,0 @@
-//----------------------------------------------------------------------------
-// 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
-//----------------------------------------------------------------------------
-//
-// Affine transformation classes.
-//
-//----------------------------------------------------------------------------
-#ifndef AGG_TRANS_AFFINE_INCLUDED
-#define AGG_TRANS_AFFINE_INCLUDED
-
-#include <math.h>
-#include "agg_basics.h"
-
-namespace agg
-{
- const double affine_epsilon = 1e-14; // About of precision of doubles
-
- //============================================================trans_affine
- //
- // See Implementation agg_trans_affine.cpp
- //
- // Affine transformation are linear transformations in Cartesian coordinates
- // (strictly speaking not only in Cartesian, but for the beginning we will
- // think so). They are rotation, scaling, translation and skewing.
- // After any affine transformation a line segment remains a line segment
- // and it will never become a curve.
- //
- // There will be no math about matrix calculations, since it has been
- // described many times. Ask yourself a very simple question:
- // "why do we need to understand and use some matrix stuff instead of just
- // rotating, scaling and so on". The answers are:
- //
- // 1. Any combination of transformations can be done by only 4 multiplications
- // and 4 additions in floating point.
- // 2. One matrix transformation is equivalent to the number of consecutive
- // discrete transformations, i.e. the matrix "accumulates" all transformations
- // in the order of their settings. Suppose we have 4 transformations:
- // * rotate by 30 degrees,
- // * scale X to 2.0,
- // * scale Y to 1.5,
- // * move to (100, 100).
- // The result will depend on the order of these transformations,
- // and the advantage of matrix is that the sequence of discret calls:
- // rotate(30), scaleX(2.0), scaleY(1.5), move(100,100)
- // will have exactly the same result as the following matrix transformations:
- //
- // affine_matrix m;
- // m *= rotate_matrix(30);
- // m *= scaleX_matrix(2.0);
- // m *= scaleY_matrix(1.5);
- // m *= move_matrix(100,100);
- //
- // m.transform_my_point_at_last(x, y);
- //
- // What is the good of it? In real life we will set-up the matrix only once
- // and then transform many points, let alone the convenience to set any
- // combination of transformations.
- //
- // So, how to use it? Very easy - literally as it's shown above. Not quite,
- // let us write a correct example:
- //
- // agg::trans_affine m;
- // m *= agg::trans_affine_rotation(30.0 * 3.1415926 / 180.0);
- // m *= agg::trans_affine_scaling(2.0, 1.5);
- // m *= agg::trans_affine_translation(100.0, 100.0);
- // m.transform(&x, &y);
- //
- // The affine matrix is all you need to perform any linear transformation,
- // but all transformations have origin point (0,0). It means that we need to
- // use 2 translations if we want to rotate someting around (100,100):
- //
- // m *= agg::trans_affine_translation(-100.0, -100.0); // move to (0,0)
- // m *= agg::trans_affine_rotation(30.0 * 3.1415926 / 180.0); // rotate
- // m *= agg::trans_affine_translation(100.0, 100.0); // move back to (100,100)
- //----------------------------------------------------------------------
- class trans_affine
- {
- public:
- //------------------------------------------ Construction
- // Construct an identity matrix - it does not transform anything
- trans_affine() :
- m0(1.0), m1(0.0), m2(0.0), m3(1.0), m4(0.0), m5(0.0)
- {}
-
- // Construct a custom matrix. Usually used in derived classes
- trans_affine(double v0, double v1, double v2, double v3, double v4, double v5) :
- m0(v0), m1(v1), m2(v2), m3(v3), m4(v4), m5(v5)
- {}
-
- // Construct a matrix to transform a parallelogram to another one.
- trans_affine(const double* rect, const double* parl)
- {
- parl_to_parl(rect, parl);
- }
-
- // Construct a matrix to transform a rectangle to a parallelogram.
- trans_affine(double x1, double y1, double x2, double y2,
- const double* parl)
- {
- rect_to_parl(x1, y1, x2, y2, parl);
- }
-
- // Construct a matrix to transform a parallelogram to a rectangle.
- trans_affine(const double* parl,
- double x1, double y1, double x2, double y2)
- {
- parl_to_rect(parl, x1, y1, x2, y2);
- }
-
-
- //---------------------------------- Parellelogram transformations
- // Calculate a matrix to transform a parallelogram to another one.
- // src and dst are pointers to arrays of three points
- // (double[6], x,y,...) that identify three corners of the
- // parallelograms assuming implicit fourth points.
- // There are also transformations rectangtle to parallelogram and
- // parellelogram to rectangle
- const trans_affine& parl_to_parl(const double* src,
- const double* dst);
-
- const trans_affine& rect_to_parl(double x1, double y1,
- double x2, double y2,
- const double* parl);
-
- const trans_affine& parl_to_rect(const double* parl,
- double x1, double y1,
- double x2, double y2);
-
-
- //------------------------------------------ Operations
- // Reset - actually load an identity matrix
- const trans_affine& reset();
-
- // Multiply matrix to another one
- const trans_affine& multiply(const trans_affine& m);
-
- // Multiply "m" to "this" and assign the result to "this"
- const trans_affine& premultiply(const trans_affine& m);
-
- // Invert matrix. Do not try to invert degenerate matrices,
- // there's no check for validity. If you set scale to 0 and
- // then try to invert matrix, expect unpredictable result.
- const trans_affine& invert();
-
- // Mirroring around X
- const trans_affine& flip_x();
-
- // Mirroring around Y
- const trans_affine& flip_y();
-
- //------------------------------------------- Load/Store
- // Store matrix to an array [6] of double
- void store_to(double* m) const
- {
- *m++ = m0; *m++ = m1; *m++ = m2; *m++ = m3; *m++ = m4; *m++ = m5;
- }
-
- // Load matrix from an array [6] of double
- const trans_affine& load_from(const double* m)
- {
- m0 = *m++; m1 = *m++; m2 = *m++; m3 = *m++; m4 = *m++; m5 = *m++;
- return *this;
- }
-
- //------------------------------------------- Operators
-
- // Multiply current matrix to another one
- const trans_affine& operator *= (const trans_affine& m)
- {
- return multiply(m);
- }
-
- // Multiply current matrix to another one and return
- // the result in a separete matrix.
- trans_affine operator * (const trans_affine& m)
- {
- return trans_affine(*this).multiply(m);
- }
-
- // Calculate and return the inverse matrix
- trans_affine operator ~ () const
- {
- trans_affine ret = *this;
- return ret.invert();
- }
-
- // Equal operator with default epsilon
- bool operator == (const trans_affine& m) const
- {
- return is_equal(m, affine_epsilon);
- }
-
- // Not Equal operator with default epsilon
- bool operator != (const trans_affine& m) const
- {
- return !is_equal(m, affine_epsilon);
- }
-
- //-------------------------------------------- Transformations
- // Direct transformation x and y
- void transform(double* x, double* y) const;
-
- // Inverse transformation x and y. It works slower than the
- // direct transformation, so if the performance is critical
- // it's better to invert() the matrix and then use transform()
- void inverse_transform(double* x, double* y) const;
-
- //-------------------------------------------- Auxiliary
- // Calculate the determinant of matrix
- double determinant() const
- {
- return 1.0 / (m0 * m3 - m1 * m2);
- }
-
- // Get the average scale (by X and Y).
- // Basically used to calculate the approximation_scale when
- // decomposinting curves into line segments.
- double scale() const;
-
- // Check to see if it's an identity matrix
- bool is_identity(double epsilon = affine_epsilon) const;
-
- // Check to see if two matrices are equal
- bool is_equal(const trans_affine& m, double epsilon = affine_epsilon) const;
-
- // Determine the major parameters. Use carefully considering degenerate matrices
- double rotation() const;
- void translation(double* dx, double* dy) const;
- void scaling(double* sx, double* sy) const;
- void scaling_abs(double* sx, double* sy) const
- {
- *sx = sqrt(m0*m0 + m2*m2);
- *sy = sqrt(m1*m1 + m3*m3);
- }
-
- private:
- double m0;
- double m1;
- double m2;
- double m3;
- double m4;
- double m5;
- };
-
- //------------------------------------------------------------------------
- inline void trans_affine::transform(double* x, double* y) const
- {
- register double tx = *x;
- *x = tx * m0 + *y * m2 + m4;
- *y = tx * m1 + *y * m3 + m5;
- }
-
- //------------------------------------------------------------------------
- inline void trans_affine::inverse_transform(double* x, double* y) const
- {
- register double d = determinant();
- register double a = (*x - m4) * d;
- register double b = (*y - m5) * d;
- *x = a * m3 - b * m2;
- *y = b * m0 - a * m1;
- }
-
- //------------------------------------------------------------------------
- inline double trans_affine::scale() const
- {
- double x = 0.707106781 * m0 + 0.707106781 * m2;
- double y = 0.707106781 * m1 + 0.707106781 * m3;
- return sqrt(x*x + y*y);
- }
-
-
- //------------------------------------------------------------------------
- inline const trans_affine& trans_affine::premultiply(const trans_affine& m)
- {
- trans_affine t = m;
- return *this = t.multiply(*this);
- }
-
-
- //====================================================trans_affine_rotation
- // Rotation matrix. sin() and cos() are calculated twice for the same angle.
- // There's no harm because the performance of sin()/cos() is very good on all
- // modern processors. Besides, this operation is not going to be invoked too
- // often.
- class trans_affine_rotation : public trans_affine
- {
- public:
- trans_affine_rotation(double a) :
- trans_affine(cos(a), sin(a), -sin(a), cos(a), 0.0, 0.0)
- {}
- };
-
- //====================================================trans_affine_scaling
- // Scaling matrix. sx, sy - scale coefficients by X and Y respectively
- class trans_affine_scaling : public trans_affine
- {
- public:
- trans_affine_scaling(double sx, double sy) :
- trans_affine(sx, 0.0, 0.0, sy, 0.0, 0.0)
- {}
-
- trans_affine_scaling(double s) :
- trans_affine(s, 0.0, 0.0, s, 0.0, 0.0)
- {}
- };
-
- //================================================trans_affine_translation
- // Translation matrix
- class trans_affine_translation : public trans_affine
- {
- public:
- trans_affine_translation(double tx, double ty) :
- trans_affine(1.0, 0.0, 0.0, 1.0, tx, ty)
- {}
- };
-
- //====================================================trans_affine_skewing
- // Sckewing (shear) matrix
- class trans_affine_skewing : public trans_affine
- {
- public:
- trans_affine_skewing(double sx, double sy) :
- trans_affine(1.0, tan(sy), tan(sx), 1.0, 0.0, 0.0)
- {}
- };
-
-
-
-}
-
-
-#endif
-