Anti-Grain Geometry Tutorial
agg_bezier_arc.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 // Arc generator. Produces at most 4 consecutive cubic bezier curves, i.e.,
17 // 4, 7, 10, or 13 vertices.
18 //
19 //----------------------------------------------------------------------------
20 
21 #ifndef AGG_BEZIER_ARC_INCLUDED
22 #define AGG_BEZIER_ARC_INCLUDED
23 
24 #include "agg_conv_transform.h"
25 
26 namespace agg
27 {
28 
29  //-----------------------------------------------------------------------
30  void arc_to_bezier(double cx, double cy, double rx, double ry,
31  double start_angle, double sweep_angle,
32  double* curve);
33 
34 
35  //==============================================================bezier_arc
36  //
37  // See implemantaion agg_bezier_arc.cpp
38  //
39  class bezier_arc
40  {
41  public:
42  //--------------------------------------------------------------------
43  bezier_arc() : m_vertex(26), m_num_vertices(0), m_cmd(path_cmd_line_to) {}
44  bezier_arc(double x, double y,
45  double rx, double ry,
46  double start_angle,
47  double sweep_angle)
48  {
49  init(x, y, rx, ry, start_angle, sweep_angle);
50  }
51 
52  //--------------------------------------------------------------------
53  void init(double x, double y,
54  double rx, double ry,
55  double start_angle,
56  double sweep_angle);
57 
58  //--------------------------------------------------------------------
59  void rewind(unsigned)
60  {
61  m_vertex = 0;
62  }
63 
64  //--------------------------------------------------------------------
65  unsigned vertex(double* x, double* y)
66  {
67  if(m_vertex >= m_num_vertices) return path_cmd_stop;
68  *x = m_vertices[m_vertex];
69  *y = m_vertices[m_vertex + 1];
70  m_vertex += 2;
71  return (m_vertex == 2) ? unsigned(path_cmd_move_to) : m_cmd;
72  }
73 
74  // Supplemantary functions. num_vertices() actually returns doubled
75  // number of vertices. That is, for 1 vertex it returns 2.
76  //--------------------------------------------------------------------
77  unsigned num_vertices() const { return m_num_vertices; }
78  const double* vertices() const { return m_vertices; }
79  double* vertices() { return m_vertices; }
80 
81  private:
82  unsigned m_vertex;
83  unsigned m_num_vertices;
84  double m_vertices[26];
85  unsigned m_cmd;
86  };
87 
88 
89 
90  //==========================================================bezier_arc_svg
91  // Compute an SVG-style bezier arc.
92  //
93  // Computes an elliptical arc from (x1, y1) to (x2, y2). The size and
94  // orientation of the ellipse are defined by two radii (rx, ry)
95  // and an x-axis-rotation, which indicates how the ellipse as a whole
96  // is rotated relative to the current coordinate system. The center
97  // (cx, cy) of the ellipse is calculated automatically to satisfy the
98  // constraints imposed by the other parameters.
99  // large-arc-flag and sweep-flag contribute to the automatic calculations
100  // and help determine how the arc is drawn.
102  {
103  public:
104  //--------------------------------------------------------------------
105  bezier_arc_svg() : m_arc(), m_radii_ok(false) {}
106 
107  bezier_arc_svg(double x1, double y1,
108  double rx, double ry,
109  double angle,
110  bool large_arc_flag,
111  bool sweep_flag,
112  double x2, double y2) :
113  m_arc(), m_radii_ok(false)
114  {
115  init(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2);
116  }
117 
118  //--------------------------------------------------------------------
119  void init(double x1, double y1,
120  double rx, double ry,
121  double angle,
122  bool large_arc_flag,
123  bool sweep_flag,
124  double x2, double y2);
125 
126  //--------------------------------------------------------------------
127  bool radii_ok() const { return m_radii_ok; }
128 
129  //--------------------------------------------------------------------
130  void rewind(unsigned)
131  {
132  m_arc.rewind(0);
133  }
134 
135  //--------------------------------------------------------------------
136  unsigned vertex(double* x, double* y)
137  {
138  return m_arc.vertex(x, y);
139  }
140 
141  // Supplemantary functions. num_vertices() actually returns doubled
142  // number of vertices. That is, for 1 vertex it returns 2.
143  //--------------------------------------------------------------------
144  unsigned num_vertices() const { return m_arc.num_vertices(); }
145  const double* vertices() const { return m_arc.vertices(); }
146  double* vertices() { return m_arc.vertices(); }
147 
148  private:
149  bezier_arc m_arc;
150  bool m_radii_ok;
151  };
152 
153 
154 
155 
156 }
157 
158 
159 #endif
Definition: agg_arc.cpp:24