1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.3
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
5 // Permission to copy, use, modify, sell and distribute this software
6 // is granted provided this copyright notice appears in all copies.
7 // This software is provided "as is" without express or implied
8 // warranty, and with no claim as to its suitability for any purpose.
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 // mcseemagg@yahoo.com
13 // http://www.antigrain.com
14 //----------------------------------------------------------------------------
16 // Affine transformations
18 //----------------------------------------------------------------------------
19 #include "agg_trans_affine.h"
26 //------------------------------------------------------------------------
27 const trans_affine
& trans_affine::parl_to_parl(const double* src
,
37 multiply(trans_affine(dst
[2] - dst
[0], dst
[3] - dst
[1],
38 dst
[4] - dst
[0], dst
[5] - dst
[1],
43 //------------------------------------------------------------------------
44 const trans_affine
& trans_affine::rect_to_parl(double x1
, double y1
,
49 src
[0] = x1
; src
[1] = y1
;
50 src
[2] = x2
; src
[3] = y1
;
51 src
[4] = x2
; src
[5] = y2
;
52 parl_to_parl(src
, parl
);
56 //------------------------------------------------------------------------
57 const trans_affine
& trans_affine::parl_to_rect(const double* parl
,
62 dst
[0] = x1
; dst
[1] = y1
;
63 dst
[2] = x2
; dst
[3] = y1
;
64 dst
[4] = x2
; dst
[5] = y2
;
65 parl_to_parl(parl
, dst
);
69 //------------------------------------------------------------------------
70 const trans_affine
& trans_affine::multiply(const trans_affine
& m
)
72 double t0
= m0
* m
.m0
+ m1
* m
.m2
;
73 double t2
= m2
* m
.m0
+ m3
* m
.m2
;
74 double t4
= m4
* m
.m0
+ m5
* m
.m2
+ m
.m4
;
75 m1
= m0
* m
.m1
+ m1
* m
.m3
;
76 m3
= m2
* m
.m1
+ m3
* m
.m3
;
77 m5
= m4
* m
.m1
+ m5
* m
.m3
+ m
.m5
;
85 //------------------------------------------------------------------------
86 const trans_affine
& trans_affine::invert()
88 double d
= determinant();
95 double t4
= -m4
* t0
- m5
* m2
;
96 m5
= -m4
* m1
- m5
* m3
;
104 //------------------------------------------------------------------------
105 const trans_affine
& trans_affine::flip_x()
113 //------------------------------------------------------------------------
114 const trans_affine
& trans_affine::flip_y()
122 //------------------------------------------------------------------------
123 const trans_affine
& trans_affine::reset()
126 m1
= m2
= m4
= m5
= 0.0;
130 //------------------------------------------------------------------------
131 inline bool is_equal_eps(double v1
, double v2
, double epsilon
)
133 return fabs(v1
- v2
) < epsilon
;
136 //------------------------------------------------------------------------
137 bool trans_affine::is_identity(double epsilon
) const
139 return is_equal_eps(m0
, 1.0, epsilon
) &&
140 is_equal_eps(m1
, 0.0, epsilon
) &&
141 is_equal_eps(m2
, 0.0, epsilon
) &&
142 is_equal_eps(m3
, 1.0, epsilon
) &&
143 is_equal_eps(m4
, 0.0, epsilon
) &&
144 is_equal_eps(m5
, 0.0, epsilon
);
147 //------------------------------------------------------------------------
148 bool trans_affine::is_equal(const trans_affine
& m
, double epsilon
) const
150 return is_equal_eps(m0
, m
.m0
, epsilon
) &&
151 is_equal_eps(m1
, m
.m1
, epsilon
) &&
152 is_equal_eps(m2
, m
.m2
, epsilon
) &&
153 is_equal_eps(m3
, m
.m3
, epsilon
) &&
154 is_equal_eps(m4
, m
.m4
, epsilon
) &&
155 is_equal_eps(m5
, m
.m5
, epsilon
);
158 //------------------------------------------------------------------------
159 double trans_affine::rotation() const
167 return atan2(y2
-y1
, x2
-x1
);
170 //------------------------------------------------------------------------
171 void trans_affine::translation(double* dx
, double* dy
) const
173 trans_affine
t(*this);
174 t
*= trans_affine_rotation(-rotation());
178 //------------------------------------------------------------------------
179 void trans_affine::scaling(double* sx
, double* sy
) const
185 trans_affine
t(*this);
186 t
*= trans_affine_rotation(-rotation());
187 t
.transform(&x1
, &y1
);
188 t
.transform(&x2
, &y2
);