17 #ifndef AGG_CURVES_INCLUDED 18 #define AGG_CURVES_INCLUDED 20 #include "agg_array.h" 28 enum curve_approximation_method_e
39 m_num_steps(0), m_step(0), m_scale(1.0) { }
43 double x3,
double y3) :
44 m_num_steps(0), m_step(0), m_scale(1.0)
46 init(x1, y1, x2, y2, x3, y3);
49 void reset() { m_num_steps = 0; m_step = -1; }
50 void init(
double x1,
double y1,
52 double x3,
double y3);
54 void approximation_method(curve_approximation_method_e) {}
55 curve_approximation_method_e approximation_method()
const {
return curve_inc; }
57 void approximation_scale(
double s);
58 double approximation_scale()
const;
60 void angle_tolerance(
double) {}
61 double angle_tolerance()
const {
return 0.0; }
63 void cusp_limit(
double) {}
64 double cusp_limit()
const {
return 0.0; }
66 void rewind(
unsigned path_id);
67 unsigned vertex(
double* x,
double* y);
98 m_approximation_scale(1.0),
99 m_angle_tolerance(0.0),
104 double x2,
double y2,
105 double x3,
double y3) :
106 m_approximation_scale(1.0),
107 m_angle_tolerance(0.0),
110 init(x1, y1, x2, y2, x3, y3);
113 void reset() { m_points.remove_all(); m_count = 0; }
114 void init(
double x1,
double y1,
115 double x2,
double y2,
116 double x3,
double y3);
118 void approximation_method(curve_approximation_method_e) {}
119 curve_approximation_method_e approximation_method()
const {
return curve_div; }
121 void approximation_scale(
double s) { m_approximation_scale = s; }
122 double approximation_scale()
const {
return m_approximation_scale; }
124 void angle_tolerance(
double a) { m_angle_tolerance = a; }
125 double angle_tolerance()
const {
return m_angle_tolerance; }
127 void cusp_limit(
double) {}
128 double cusp_limit()
const {
return 0.0; }
130 void rewind(
unsigned)
135 unsigned vertex(
double* x,
double* y)
137 if(m_count >= m_points.size())
return path_cmd_stop;
138 const point_d& p = m_points[m_count++];
141 return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to;
145 void bezier(
double x1,
double y1,
146 double x2,
double y2,
147 double x3,
double y3);
148 void recursive_bezier(
double x1,
double y1,
149 double x2,
double y2,
150 double x3,
double y3,
153 double m_approximation_scale;
154 double m_distance_tolerance_square;
155 double m_angle_tolerance;
172 double x2,
double y2,
173 double x3,
double y3,
174 double x4,
double y4)
176 cp[0] = x1; cp[1] = y1; cp[2] = x2; cp[3] = y2;
177 cp[4] = x3; cp[5] = y3; cp[6] = x4; cp[7] = y4;
179 void init(
double x1,
double y1,
180 double x2,
double y2,
181 double x3,
double y3,
182 double x4,
double y4)
184 cp[0] = x1; cp[1] = y1; cp[2] = x2; cp[3] = y2;
185 cp[4] = x3; cp[5] = y3; cp[6] = x4; cp[7] = y4;
187 double operator [] (
unsigned i)
const {
return cp[i]; }
188 double& operator [] (
unsigned i) {
return cp[i]; }
198 m_num_steps(0), m_step(0), m_scale(1.0) { }
201 double x2,
double y2,
202 double x3,
double y3,
203 double x4,
double y4) :
204 m_num_steps(0), m_step(0), m_scale(1.0)
206 init(x1, y1, x2, y2, x3, y3, x4, y4);
210 m_num_steps(0), m_step(0), m_scale(1.0)
212 init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
215 void reset() { m_num_steps = 0; m_step = -1; }
216 void init(
double x1,
double y1,
217 double x2,
double y2,
218 double x3,
double y3,
219 double x4,
double y4);
223 init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
226 void approximation_method(curve_approximation_method_e) {}
227 curve_approximation_method_e approximation_method()
const {
return curve_inc; }
229 void approximation_scale(
double s);
230 double approximation_scale()
const;
232 void angle_tolerance(
double) {}
233 double angle_tolerance()
const {
return 0.0; }
235 void cusp_limit(
double) {}
236 double cusp_limit()
const {
return 0.0; }
238 void rewind(
unsigned path_id);
239 unsigned vertex(
double* x,
double* y);
269 double x2,
double y2,
270 double x3,
double y3,
271 double x4,
double y4)
283 (-x1 + 6*x2 + x3) / 6,
284 (-y1 + 6*y2 + y3) / 6,
285 ( x2 + 6*x3 - x4) / 6,
286 ( y2 + 6*y3 - y4) / 6,
296 return catrom_to_bezier(cp[0], cp[1], cp[2], cp[3],
297 cp[4], cp[5], cp[6], cp[7]);
303 inline curve4_points ubspline_to_bezier(
double x1,
double y1,
304 double x2,
double y2,
305 double x3,
double y3,
306 double x4,
double y4)
316 (x1 + 4*x2 + x3) / 6,
317 (y1 + 4*y2 + y3) / 6,
322 (x2 + 4*x3 + x4) / 6,
323 (y2 + 4*y3 + y4) / 6);
331 return ubspline_to_bezier(cp[0], cp[1], cp[2], cp[3],
332 cp[4], cp[5], cp[6], cp[7]);
340 double x2,
double y2,
341 double x3,
double y3,
342 double x4,
double y4)
368 return hermite_to_bezier(cp[0], cp[1], cp[2], cp[3],
369 cp[4], cp[5], cp[6], cp[7]);
378 m_approximation_scale(1.0),
379 m_angle_tolerance(0.0),
385 double x2,
double y2,
386 double x3,
double y3,
387 double x4,
double y4) :
388 m_approximation_scale(1.0),
389 m_angle_tolerance(0.0),
393 init(x1, y1, x2, y2, x3, y3, x4, y4);
397 m_approximation_scale(1.0),
398 m_angle_tolerance(0.0),
401 init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
404 void reset() { m_points.remove_all(); m_count = 0; }
405 void init(
double x1,
double y1,
406 double x2,
double y2,
407 double x3,
double y3,
408 double x4,
double y4);
412 init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
415 void approximation_method(curve_approximation_method_e) {}
417 curve_approximation_method_e approximation_method()
const 422 void approximation_scale(
double s) { m_approximation_scale = s; }
423 double approximation_scale()
const {
return m_approximation_scale; }
425 void angle_tolerance(
double a) { m_angle_tolerance = a; }
426 double angle_tolerance()
const {
return m_angle_tolerance; }
428 void cusp_limit(
double v)
430 m_cusp_limit = (v == 0.0) ? 0.0 : pi - v;
433 double cusp_limit()
const 435 return (m_cusp_limit == 0.0) ? 0.0 : pi - m_cusp_limit;
438 void rewind(
unsigned)
443 unsigned vertex(
double* x,
double* y)
445 if(m_count >= m_points.size())
return path_cmd_stop;
446 const point_d& p = m_points[m_count++];
449 return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to;
453 void bezier(
double x1,
double y1,
454 double x2,
double y2,
455 double x3,
double y3,
456 double x4,
double y4);
458 void recursive_bezier(
double x1,
double y1,
459 double x2,
double y2,
460 double x3,
double y3,
461 double x4,
double y4,
464 double m_approximation_scale;
465 double m_distance_tolerance_square;
466 double m_angle_tolerance;
477 curve3() : m_approximation_method(curve_div) {}
478 curve3(
double x1,
double y1,
479 double x2,
double y2,
480 double x3,
double y3) :
481 m_approximation_method(curve_div)
483 init(x1, y1, x2, y2, x3, y3);
492 void init(
double x1,
double y1,
493 double x2,
double y2,
494 double x3,
double y3)
496 if(m_approximation_method == curve_inc)
498 m_curve_inc.init(x1, y1, x2, y2, x3, y3);
502 m_curve_div.init(x1, y1, x2, y2, x3, y3);
506 void approximation_method(curve_approximation_method_e v)
508 m_approximation_method = v;
511 curve_approximation_method_e approximation_method()
const 513 return m_approximation_method;
516 void approximation_scale(
double s)
518 m_curve_inc.approximation_scale(s);
519 m_curve_div.approximation_scale(s);
522 double approximation_scale()
const 524 return m_curve_inc.approximation_scale();
527 void angle_tolerance(
double a)
529 m_curve_div.angle_tolerance(a);
532 double angle_tolerance()
const 534 return m_curve_div.angle_tolerance();
537 void cusp_limit(
double v)
539 m_curve_div.cusp_limit(v);
542 double cusp_limit()
const 544 return m_curve_div.cusp_limit();
547 void rewind(
unsigned path_id)
549 if(m_approximation_method == curve_inc)
551 m_curve_inc.rewind(path_id);
555 m_curve_div.rewind(path_id);
559 unsigned vertex(
double* x,
double* y)
561 if(m_approximation_method == curve_inc)
563 return m_curve_inc.vertex(x, y);
565 return m_curve_div.vertex(x, y);
571 curve_approximation_method_e m_approximation_method;
582 curve4() : m_approximation_method(curve_div) {}
583 curve4(
double x1,
double y1,
584 double x2,
double y2,
585 double x3,
double y3,
586 double x4,
double y4) :
587 m_approximation_method(curve_div)
589 init(x1, y1, x2, y2, x3, y3, x4, y4);
593 m_approximation_method(curve_div)
595 init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
604 void init(
double x1,
double y1,
605 double x2,
double y2,
606 double x3,
double y3,
607 double x4,
double y4)
609 if(m_approximation_method == curve_inc)
611 m_curve_inc.init(x1, y1, x2, y2, x3, y3, x4, y4);
615 m_curve_div.init(x1, y1, x2, y2, x3, y3, x4, y4);
621 init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
624 void approximation_method(curve_approximation_method_e v)
626 m_approximation_method = v;
629 curve_approximation_method_e approximation_method()
const 631 return m_approximation_method;
634 void approximation_scale(
double s)
636 m_curve_inc.approximation_scale(s);
637 m_curve_div.approximation_scale(s);
639 double approximation_scale()
const {
return m_curve_inc.approximation_scale(); }
641 void angle_tolerance(
double v)
643 m_curve_div.angle_tolerance(v);
646 double angle_tolerance()
const 648 return m_curve_div.angle_tolerance();
651 void cusp_limit(
double v)
653 m_curve_div.cusp_limit(v);
656 double cusp_limit()
const 658 return m_curve_div.cusp_limit();
661 void rewind(
unsigned path_id)
663 if(m_approximation_method == curve_inc)
665 m_curve_inc.rewind(path_id);
669 m_curve_div.rewind(path_id);
673 unsigned vertex(
double* x,
double* y)
675 if(m_approximation_method == curve_inc)
677 return m_curve_inc.vertex(x, y);
679 return m_curve_div.vertex(x, y);
685 curve_approximation_method_e m_approximation_method;