Anti-Grain Geometry Tutorial
agg_trans_bilinear.h
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 // Bilinear 2D transformations
17 //
18 //----------------------------------------------------------------------------
19 #ifndef AGG_TRANS_BILINEAR_INCLUDED
20 #define AGG_TRANS_BILINEAR_INCLUDED
21 
22 #include "agg_basics.h"
23 #include "agg_simul_eq.h"
24 
25 namespace agg
26 {
27 
28  //==========================================================trans_bilinear
30  {
31  public:
32  //--------------------------------------------------------------------
33  trans_bilinear() : m_valid(false) {}
34 
35  //--------------------------------------------------------------------
36  // Arbitrary quadrangle transformations
37  trans_bilinear(const double* src, const double* dst)
38  {
39  quad_to_quad(src, dst);
40  }
41 
42 
43  //--------------------------------------------------------------------
44  // Direct transformations
45  trans_bilinear(double x1, double y1, double x2, double y2,
46  const double* quad)
47  {
48  rect_to_quad(x1, y1, x2, y2, quad);
49  }
50 
51 
52  //--------------------------------------------------------------------
53  // Reverse transformations
54  trans_bilinear(const double* quad,
55  double x1, double y1, double x2, double y2)
56  {
57  quad_to_rect(quad, x1, y1, x2, y2);
58  }
59 
60 
61  //--------------------------------------------------------------------
62  // Set the transformations using two arbitrary quadrangles.
63  void quad_to_quad(const double* src, const double* dst)
64  {
65  double left[4][4];
66  double right[4][2];
67 
68  unsigned i;
69  for(i = 0; i < 4; i++)
70  {
71  unsigned ix = i * 2;
72  unsigned iy = ix + 1;
73  left[i][0] = 1.0;
74  left[i][1] = src[ix] * src[iy];
75  left[i][2] = src[ix];
76  left[i][3] = src[iy];
77 
78  right[i][0] = dst[ix];
79  right[i][1] = dst[iy];
80  }
81  m_valid = simul_eq<4, 2>::solve(left, right, m_mtx);
82  }
83 
84 
85  //--------------------------------------------------------------------
86  // Set the direct transformations, i.e., rectangle -> quadrangle
87  void rect_to_quad(double x1, double y1, double x2, double y2,
88  const double* quad)
89  {
90  double src[8];
91  src[0] = src[6] = x1;
92  src[2] = src[4] = x2;
93  src[1] = src[3] = y1;
94  src[5] = src[7] = y2;
95  quad_to_quad(src, quad);
96  }
97 
98 
99  //--------------------------------------------------------------------
100  // Set the reverse transformations, i.e., quadrangle -> rectangle
101  void quad_to_rect(const double* quad,
102  double x1, double y1, double x2, double y2)
103  {
104  double dst[8];
105  dst[0] = dst[6] = x1;
106  dst[2] = dst[4] = x2;
107  dst[1] = dst[3] = y1;
108  dst[5] = dst[7] = y2;
109  quad_to_quad(quad, dst);
110  }
111 
112  //--------------------------------------------------------------------
113  // Check if the equations were solved successfully
114  bool is_valid() const { return m_valid; }
115 
116  //--------------------------------------------------------------------
117  // Transform a point (x, y)
118  void transform(double* x, double* y) const
119  {
120  double tx = *x;
121  double ty = *y;
122  double xy = tx * ty;
123  *x = m_mtx[0][0] + m_mtx[1][0] * xy + m_mtx[2][0] * tx + m_mtx[3][0] * ty;
124  *y = m_mtx[0][1] + m_mtx[1][1] * xy + m_mtx[2][1] * tx + m_mtx[3][1] * ty;
125  }
126 
127 
128  //--------------------------------------------------------------------
130  {
131  double inc_x;
132  double inc_y;
133 
134  public:
135  double x;
136  double y;
137 
138  iterator_x() {}
139  iterator_x(double tx, double ty, double step, const double m[4][2]) :
140  inc_x(m[1][0] * step * ty + m[2][0] * step),
141  inc_y(m[1][1] * step * ty + m[2][1] * step),
142  x(m[0][0] + m[1][0] * tx * ty + m[2][0] * tx + m[3][0] * ty),
143  y(m[0][1] + m[1][1] * tx * ty + m[2][1] * tx + m[3][1] * ty)
144  {
145  }
146 
147  void operator ++ ()
148  {
149  x += inc_x;
150  y += inc_y;
151  }
152  };
153 
154  iterator_x begin(double x, double y, double step) const
155  {
156  return iterator_x(x, y, step, m_mtx);
157  }
158 
159  private:
160  double m_mtx[4][2];
161  bool m_valid;
162  };
163 
164 }
165 
166 #endif
Definition: agg_arc.cpp:24