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) ? 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. 101 class bezier_arc_svg 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 160