1 //---------------------------------------------------------------------------- 2 // Anti-Grain Geometry - Version 2.2 3 // Copyright (C) 2002-2004 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) {} 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 : path_cmd_curve4; 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 }; 86 87 88 89 //==========================================================bezier_arc_svg 90 // Compute an SVG-style bezier arc. 91 // 92 // Computes an elliptical arc from (x1, y1) to (x2, y2). The size and 93 // orientation of the ellipse are defined by two radii (rx, ry) 94 // and an x-axis-rotation, which indicates how the ellipse as a whole 95 // is rotated relative to the current coordinate system. The center 96 // (cx, cy) of the ellipse is calculated automatically to satisfy the 97 // constraints imposed by the other parameters. 98 // large-arc-flag and sweep-flag contribute to the automatic calculations 99 // and help determine how the arc is drawn. 100 class bezier_arc_svg 101 { 102 public: 103 //-------------------------------------------------------------------- 104 bezier_arc_svg() : m_arc(), m_radii_ok(false) {} 105 106 bezier_arc_svg(double x1, double y1, 107 double rx, double ry, 108 double angle, 109 bool large_arc_flag, 110 bool sweep_flag, 111 double x2, double y2) : 112 m_arc(), m_radii_ok(false) 113 { 114 init(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2); 115 } 116 117 //-------------------------------------------------------------------- 118 void init(double x1, double y1, 119 double rx, double ry, 120 double angle, 121 bool large_arc_flag, 122 bool sweep_flag, 123 double x2, double y2); 124 125 //-------------------------------------------------------------------- 126 bool radii_ok() const { return m_radii_ok; } 127 128 //-------------------------------------------------------------------- 129 void rewind(unsigned) 130 { 131 m_arc.rewind(0); 132 } 133 134 //-------------------------------------------------------------------- 135 unsigned vertex(double* x, double* y) 136 { 137 return m_arc.vertex(x, y); 138 } 139 140 // Supplemantary functions. num_vertices() actually returns doubled 141 // number of vertices. That is, for 1 vertex it returns 2. 142 //-------------------------------------------------------------------- 143 unsigned num_vertices() const { return m_arc.num_vertices(); } 144 const double* vertices() const { return m_arc.vertices(); } 145 double* vertices() { return m_arc.vertices(); } 146 147 private: 148 bezier_arc m_arc; 149 bool m_radii_ok; 150 }; 151 152 153 154 155 } 156 157 158 #endif 159