Anti-Grain Geometry Tutorial
agg_dda_line.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 // classes dda_line_interpolator, dda2_line_interpolator
17 //
18 //----------------------------------------------------------------------------
19 
20 #ifndef AGG_DDA_LINE_INCLUDED
21 #define AGG_DDA_LINE_INCLUDED
22 
23 #include <cstdlib>
24 #include "agg_basics.h"
25 
26 namespace agg
27 {
28 
29  //===================================================dda_line_interpolator
30  template<int FractionShift, int YShift=0> class dda_line_interpolator
31  {
32  public:
33  //--------------------------------------------------------------------
35 
36  //--------------------------------------------------------------------
37  dda_line_interpolator(int y1, int y2, unsigned count) :
38  m_y(y1),
39  m_inc(((y2 - y1) << FractionShift) / int(count)),
40  m_dy(0)
41  {
42  }
43 
44  //--------------------------------------------------------------------
45  void operator ++ ()
46  {
47  m_dy += m_inc;
48  }
49 
50  //--------------------------------------------------------------------
51  void operator -- ()
52  {
53  m_dy -= m_inc;
54  }
55 
56  //--------------------------------------------------------------------
57  void operator += (unsigned n)
58  {
59  m_dy += m_inc * n;
60  }
61 
62  //--------------------------------------------------------------------
63  void operator -= (unsigned n)
64  {
65  m_dy -= m_inc * n;
66  }
67 
68 
69  //--------------------------------------------------------------------
70  int y() const { return m_y + (m_dy >> (FractionShift-YShift)); }
71  int dy() const { return m_dy; }
72 
73 
74  private:
75  int m_y;
76  int m_inc;
77  int m_dy;
78  };
79 
80 
81 
82 
83 
84  //=================================================dda2_line_interpolator
86  {
87  public:
88  typedef int save_data_type;
89  enum save_size_e { save_size = 2 };
90 
91  //--------------------------------------------------------------------
93 
94  //-------------------------------------------- Forward-adjusted line
95  dda2_line_interpolator(int y1, int y2, int count) :
96  m_cnt(count <= 0 ? 1 : count),
97  m_lft((y2 - y1) / m_cnt),
98  m_rem((y2 - y1) % m_cnt),
99  m_mod(m_rem),
100  m_y(y1)
101  {
102  if(m_mod <= 0)
103  {
104  m_mod += count;
105  m_rem += count;
106  m_lft--;
107  }
108  m_mod -= count;
109  }
110 
111  //-------------------------------------------- Backward-adjusted line
112  dda2_line_interpolator(int y1, int y2, int count, int) :
113  m_cnt(count <= 0 ? 1 : count),
114  m_lft((y2 - y1) / m_cnt),
115  m_rem((y2 - y1) % m_cnt),
116  m_mod(m_rem),
117  m_y(y1)
118  {
119  if(m_mod <= 0)
120  {
121  m_mod += count;
122  m_rem += count;
123  m_lft--;
124  }
125  }
126 
127  //-------------------------------------------- Backward-adjusted line
128  dda2_line_interpolator(int y, int count) :
129  m_cnt(count <= 0 ? 1 : count),
130  m_lft(y / m_cnt),
131  m_rem(y % m_cnt),
132  m_mod(m_rem),
133  m_y(0)
134  {
135  if(m_mod <= 0)
136  {
137  m_mod += count;
138  m_rem += count;
139  m_lft--;
140  }
141  }
142 
143 
144  //--------------------------------------------------------------------
145  void save(save_data_type* data) const
146  {
147  data[0] = m_mod;
148  data[1] = m_y;
149  }
150 
151  //--------------------------------------------------------------------
152  void load(const save_data_type* data)
153  {
154  m_mod = data[0];
155  m_y = data[1];
156  }
157 
158  //--------------------------------------------------------------------
159  void operator++()
160  {
161  m_mod += m_rem;
162  m_y += m_lft;
163  if(m_mod > 0)
164  {
165  m_mod -= m_cnt;
166  m_y++;
167  }
168  }
169 
170  //--------------------------------------------------------------------
171  void operator--()
172  {
173  if(m_mod <= m_rem)
174  {
175  m_mod += m_cnt;
176  m_y--;
177  }
178  m_mod -= m_rem;
179  m_y -= m_lft;
180  }
181 
182  //--------------------------------------------------------------------
183  void adjust_forward()
184  {
185  m_mod -= m_cnt;
186  }
187 
188  //--------------------------------------------------------------------
189  void adjust_backward()
190  {
191  m_mod += m_cnt;
192  }
193 
194  //--------------------------------------------------------------------
195  int mod() const { return m_mod; }
196  int rem() const { return m_rem; }
197  int lft() const { return m_lft; }
198 
199  //--------------------------------------------------------------------
200  int y() const { return m_y; }
201 
202  private:
203  int m_cnt;
204  int m_lft;
205  int m_rem;
206  int m_mod;
207  int m_y;
208  };
209 
210 
211 
212 
213 
214 
215 
216  //---------------------------------------------line_bresenham_interpolator
218  {
219  public:
220  enum subpixel_scale_e
221  {
222  subpixel_shift = 8,
223  subpixel_scale = 1 << subpixel_shift,
224  subpixel_mask = subpixel_scale - 1
225  };
226 
227  //--------------------------------------------------------------------
228  static int line_lr(int v) { return v >> subpixel_shift; }
229 
230  //--------------------------------------------------------------------
231  line_bresenham_interpolator(int x1, int y1, int x2, int y2) :
232  m_x1_lr(line_lr(x1)),
233  m_y1_lr(line_lr(y1)),
234  m_x2_lr(line_lr(x2)),
235  m_y2_lr(line_lr(y2)),
236  m_ver(std::abs(m_x2_lr - m_x1_lr) < std::abs(m_y2_lr - m_y1_lr)),
237  m_len(m_ver ? std::abs(m_y2_lr - m_y1_lr) :
238  std::abs(m_x2_lr - m_x1_lr)),
239  m_inc(m_ver ? ((y2 > y1) ? 1 : -1) : ((x2 > x1) ? 1 : -1)),
240  m_interpolator(m_ver ? x1 : y1,
241  m_ver ? x2 : y2,
242  m_len)
243  {
244  }
245 
246  //--------------------------------------------------------------------
247  bool is_ver() const { return m_ver; }
248  unsigned len() const { return m_len; }
249  int inc() const { return m_inc; }
250 
251  //--------------------------------------------------------------------
252  void hstep()
253  {
254  ++m_interpolator;
255  m_x1_lr += m_inc;
256  }
257 
258  //--------------------------------------------------------------------
259  void vstep()
260  {
261  ++m_interpolator;
262  m_y1_lr += m_inc;
263  }
264 
265  //--------------------------------------------------------------------
266  int x1() const { return m_x1_lr; }
267  int y1() const { return m_y1_lr; }
268  int x2() const { return line_lr(m_interpolator.y()); }
269  int y2() const { return line_lr(m_interpolator.y()); }
270  int x2_hr() const { return m_interpolator.y(); }
271  int y2_hr() const { return m_interpolator.y(); }
272 
273  private:
274  int m_x1_lr;
275  int m_y1_lr;
276  int m_x2_lr;
277  int m_y2_lr;
278  bool m_ver;
279  unsigned m_len;
280  int m_inc;
281  dda2_line_interpolator m_interpolator;
282 
283  };
284 
285 
286 }
287 
288 
289 
290 #endif
Definition: agg_arc.cpp:24