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 bezier_arc() : m_vertex(26) {} 43 bezier_arc(double x, double y, 44 double rx, double ry, 45 double start_angle, 46 double sweep_angle) 47 { 48 init(x, y, rx, ry, start_angle, sweep_angle); 49 } 50 51 void init(double x, double y, 52 double rx, double ry, 53 double start_angle, 54 double sweep_angle); 55 56 //-------------------------------------------------------------------- 57 void rewind(unsigned) 58 { 59 m_vertex = 0; 60 } 61 62 //-------------------------------------------------------------------- 63 unsigned vertex(double* x, double* y) 64 { 65 if(m_vertex >= m_num_vertices) return path_cmd_stop; 66 *x = m_vertices[m_vertex]; 67 *y = m_vertices[m_vertex + 1]; 68 m_vertex += 2; 69 return (m_vertex == 2) ? path_cmd_move_to : path_cmd_curve4; 70 } 71 72 // Supplemantary functions. num_vertices() actually returns doubled 73 // number of vertices. That is, for 1 vertex it returns 2. 74 //-------------------------------------------------------------------- 75 unsigned num_vertices() const { return m_num_vertices; } 76 const double* vertices() const { return m_vertices; } 77 double* vertices() { return m_vertices; } 78 79 private: 80 unsigned m_vertex; 81 unsigned m_num_vertices; 82 double m_vertices[26]; 83 }; 84 85 86 87 //==========================================================bezier_arc_svg 88 // Compute an SVG-style bezier arc. 89 // 90 // Computes an elliptical arc from (x1, y1) to (x2, y2). The size and 91 // orientation of the ellipse are defined by two radii (rx, ry) 92 // and an x-axis-rotation, which indicates how the ellipse as a whole 93 // is rotated relative to the current coordinate system. The center 94 // (cx, cy) of the ellipse is calculated automatically to satisfy the 95 // constraints imposed by the other parameters. 96 // large-arc-flag and sweep-flag contribute to the automatic calculations 97 // and help determine how the arc is drawn. 98 class bezier_arc_svg 99 { 100 public: 101 //-------------------------------------------------------------------- 102 bezier_arc_svg() : m_arc(), m_radii_ok(false) {} 103 104 bezier_arc_svg(double x1, double y1, 105 double rx, double ry, 106 double angle, 107 bool large_arc_flag, 108 bool sweep_flag, 109 double x2, double y2) : 110 m_arc(), m_radii_ok(false) 111 { 112 init(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2); 113 } 114 115 //-------------------------------------------------------------------- 116 void init(double x1, double y1, 117 double rx, double ry, 118 double angle, 119 bool large_arc_flag, 120 bool sweep_flag, 121 double x2, double y2); 122 123 //-------------------------------------------------------------------- 124 bool radii_ok() const { return m_radii_ok; } 125 126 //-------------------------------------------------------------------- 127 void rewind(unsigned) 128 { 129 m_arc.rewind(0); 130 } 131 132 //-------------------------------------------------------------------- 133 unsigned vertex(double* x, double* y) 134 { 135 return m_arc.vertex(x, y); 136 } 137 138 // Supplemantary functions. num_vertices() actually returns doubled 139 // number of vertices. That is, for 1 vertex it returns 2. 140 //-------------------------------------------------------------------- 141 unsigned num_vertices() const { return m_arc.num_vertices(); } 142 const double* vertices() const { return m_arc.vertices(); } 143 double* vertices() { return m_arc.vertices(); } 144 145 private: 146 bezier_arc m_arc; 147 bool m_radii_ok; 148 }; 149 150 151 152 153 } 154 155 156 #endif 157