Anti-Grain Geometry Tutorial
agg_ellipse.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 // class ellipse
17 //
18 //----------------------------------------------------------------------------
19 
20 #ifndef AGG_ELLIPSE_INCLUDED
21 #define AGG_ELLIPSE_INCLUDED
22 
23 #include "agg_basics.h"
24 #include <cmath>
25 
26 namespace agg
27 {
28 
29  //----------------------------------------------------------------ellipse
30  class ellipse
31  {
32  public:
33  ellipse() :
34  m_x(0.0), m_y(0.0), m_rx(1.0), m_ry(1.0), m_scale(1.0),
35  m_num(4), m_step(0), m_cw(false) {}
36 
37  ellipse(double x, double y, double rx, double ry,
38  unsigned num_steps=0, bool cw=false) :
39  m_x(x), m_y(y), m_rx(rx), m_ry(ry), m_scale(1.0),
40  m_num(num_steps), m_step(0), m_cw(cw)
41  {
42  if(m_num == 0) calc_num_steps();
43  }
44 
45  void init(double x, double y, double rx, double ry,
46  unsigned num_steps=0, bool cw=false);
47 
48  void approximation_scale(double scale);
49  void rewind(unsigned path_id);
50  unsigned vertex(double* x, double* y);
51 
52  private:
53  void calc_num_steps();
54 
55  double m_x;
56  double m_y;
57  double m_rx;
58  double m_ry;
59  double m_scale;
60  unsigned m_num;
61  unsigned m_step;
62  bool m_cw;
63  };
64 
65  //------------------------------------------------------------------------
66  inline void ellipse::init(double x, double y, double rx, double ry,
67  unsigned num_steps, bool cw)
68  {
69  m_x = x;
70  m_y = y;
71  m_rx = rx;
72  m_ry = ry;
73  m_num = num_steps;
74  m_step = 0;
75  m_cw = cw;
76  if(m_num == 0) calc_num_steps();
77  }
78 
79  //------------------------------------------------------------------------
80  inline void ellipse::approximation_scale(double scale)
81  {
82  m_scale = scale;
83  calc_num_steps();
84  }
85 
86  //------------------------------------------------------------------------
87  inline void ellipse::calc_num_steps()
88  {
89  double ra = (std::fabs(m_rx) + std::fabs(m_ry)) / 2;
90  double da = std::acos(ra / (ra + 0.125 / m_scale)) * 2;
91  m_num = uround(2*pi / da);
92  }
93 
94  //------------------------------------------------------------------------
95  inline void ellipse::rewind(unsigned)
96  {
97  m_step = 0;
98  }
99 
100  //------------------------------------------------------------------------
101  inline unsigned ellipse::vertex(double* x, double* y)
102  {
103  if(m_step == m_num)
104  {
105  ++m_step;
106  return path_cmd_end_poly | path_flags_close | path_flags_ccw;
107  }
108  if(m_step > m_num) return path_cmd_stop;
109  double angle = double(m_step) / double(m_num) * 2.0 * pi;
110  if(m_cw) angle = 2.0 * pi - angle;
111  *x = m_x + std::cos(angle) * m_rx;
112  *y = m_y + std::sin(angle) * m_ry;
113  m_step++;
114  return ((m_step == 1) ? path_cmd_move_to : path_cmd_line_to);
115  }
116 
117 }
118 
119 
120 
121 #endif
122 
123 
Definition: agg_arc.cpp:24