Anti-Grain Geometry Tutorial
agg_trans_affine.cpp
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4 //
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.
9 //
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 // mcseemagg@yahoo.com
13 // http://www.antigrain.com
14 //----------------------------------------------------------------------------
15 //
16 // Affine transformations
17 //
18 //----------------------------------------------------------------------------
19 #include "agg_trans_affine.h"
20 
21 
22 
23 namespace agg
24 {
25 
26  //------------------------------------------------------------------------
27  const trans_affine& trans_affine::parl_to_parl(const double* src,
28  const double* dst)
29  {
30  sx = src[2] - src[0];
31  shy = src[3] - src[1];
32  shx = src[4] - src[0];
33  sy = src[5] - src[1];
34  tx = src[0];
35  ty = src[1];
36  invert();
37  multiply(trans_affine(dst[2] - dst[0], dst[3] - dst[1],
38  dst[4] - dst[0], dst[5] - dst[1],
39  dst[0], dst[1]));
40  return *this;
41  }
42 
43  //------------------------------------------------------------------------
44  const trans_affine& trans_affine::rect_to_parl(double x1, double y1,
45  double x2, double y2,
46  const double* parl)
47  {
48  double src[6];
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);
53  return *this;
54  }
55 
56  //------------------------------------------------------------------------
57  const trans_affine& trans_affine::parl_to_rect(const double* parl,
58  double x1, double y1,
59  double x2, double y2)
60  {
61  double dst[6];
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);
66  return *this;
67  }
68 
69  //------------------------------------------------------------------------
70  const trans_affine& trans_affine::multiply(const trans_affine& m)
71  {
72  double t0 = sx * m.sx + shy * m.shx;
73  double t2 = shx * m.sx + sy * m.shx;
74  double t4 = tx * m.sx + ty * m.shx + m.tx;
75  shy = sx * m.shy + shy * m.sy;
76  sy = shx * m.shy + sy * m.sy;
77  ty = tx * m.shy + ty * m.sy + m.ty;
78  sx = t0;
79  shx = t2;
80  tx = t4;
81  return *this;
82  }
83 
84 
85  //------------------------------------------------------------------------
86  const trans_affine& trans_affine::invert()
87  {
88  double d = determinant_reciprocal();
89 
90  double t0 = sy * d;
91  sy = sx * d;
92  shy = -shy * d;
93  shx = -shx * d;
94 
95  double t4 = -tx * t0 - ty * shx;
96  ty = -tx * shy - ty * sy;
97 
98  sx = t0;
99  tx = t4;
100  return *this;
101  }
102 
103 
104  //------------------------------------------------------------------------
105  const trans_affine& trans_affine::flip_x()
106  {
107  sx = -sx;
108  shy = -shy;
109  tx = -tx;
110  return *this;
111  }
112 
113  //------------------------------------------------------------------------
114  const trans_affine& trans_affine::flip_y()
115  {
116  shx = -shx;
117  sy = -sy;
118  ty = -ty;
119  return *this;
120  }
121 
122  //------------------------------------------------------------------------
123  const trans_affine& trans_affine::reset()
124  {
125  sx = sy = 1.0;
126  shy = shx = tx = ty = 0.0;
127  return *this;
128  }
129 
130  //------------------------------------------------------------------------
131  bool trans_affine::is_identity(double epsilon) const
132  {
133  return is_equal_eps(sx, 1.0, epsilon) &&
134  is_equal_eps(shy, 0.0, epsilon) &&
135  is_equal_eps(shx, 0.0, epsilon) &&
136  is_equal_eps(sy, 1.0, epsilon) &&
137  is_equal_eps(tx, 0.0, epsilon) &&
138  is_equal_eps(ty, 0.0, epsilon);
139  }
140 
141  //------------------------------------------------------------------------
142  bool trans_affine::is_valid(double epsilon) const
143  {
144  return std::fabs(sx) > epsilon && std::fabs(sy) > epsilon;
145  }
146 
147  //------------------------------------------------------------------------
148  bool trans_affine::is_equal(const trans_affine& m, double epsilon) const
149  {
150  return is_equal_eps(sx, m.sx, epsilon) &&
151  is_equal_eps(shy, m.shy, epsilon) &&
152  is_equal_eps(shx, m.shx, epsilon) &&
153  is_equal_eps(sy, m.sy, epsilon) &&
154  is_equal_eps(tx, m.tx, epsilon) &&
155  is_equal_eps(ty, m.ty, epsilon);
156  }
157 
158  //------------------------------------------------------------------------
159  double trans_affine::rotation() const
160  {
161  double x1 = 0.0;
162  double y1 = 0.0;
163  double x2 = 1.0;
164  double y2 = 0.0;
165  transform(&x1, &y1);
166  transform(&x2, &y2);
167  return std::atan2(y2-y1, x2-x1);
168  }
169 
170  //------------------------------------------------------------------------
171  void trans_affine::translation(double* dx, double* dy) const
172  {
173  *dx = tx;
174  *dy = ty;
175  }
176 
177  //------------------------------------------------------------------------
178  void trans_affine::scaling(double* x, double* y) const
179  {
180  double x1 = 0.0;
181  double y1 = 0.0;
182  double x2 = 1.0;
183  double y2 = 1.0;
184  trans_affine t(*this);
185  t *= trans_affine_rotation(-rotation());
186  t.transform(&x1, &y1);
187  t.transform(&x2, &y2);
188  *x = x2 - x1;
189  *y = y2 - y1;
190  }
191 
192 
193 }
194 
Definition: agg_arc.cpp:24