agg_bezier_arc.h 5.6 KB

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