1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.3
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
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.
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 // mcseemagg@yahoo.com
13 // http://www.antigrain.com
14 //----------------------------------------------------------------------------
16 #include "agg_vcgen_bspline.h"
21 //------------------------------------------------------------------------
22 vcgen_bspline::vcgen_bspline() :
26 m_interpolation_step(1.0/50.0),
34 //------------------------------------------------------------------------
35 void vcgen_bspline::remove_all()
37 m_src_vertices
.remove_all();
44 //------------------------------------------------------------------------
45 void vcgen_bspline::add_vertex(double x
, double y
, unsigned cmd
)
50 m_src_vertices
.modify_last(point_type(x
, y
));
56 m_src_vertices
.add(point_type(x
, y
));
60 m_closed
= get_close_flag(cmd
);
66 //------------------------------------------------------------------------
67 void vcgen_bspline::rewind(unsigned)
72 if(m_status
== initial
&& m_src_vertices
.size() > 2)
76 m_spline_x
.init(m_src_vertices
.size() + 8);
77 m_spline_y
.init(m_src_vertices
.size() + 8);
78 m_spline_x
.add_point(0.0, m_src_vertices
.prev(m_src_vertices
.size() - 3).x
);
79 m_spline_y
.add_point(0.0, m_src_vertices
.prev(m_src_vertices
.size() - 3).y
);
80 m_spline_x
.add_point(1.0, m_src_vertices
[m_src_vertices
.size() - 3].x
);
81 m_spline_y
.add_point(1.0, m_src_vertices
[m_src_vertices
.size() - 3].y
);
82 m_spline_x
.add_point(2.0, m_src_vertices
[m_src_vertices
.size() - 2].x
);
83 m_spline_y
.add_point(2.0, m_src_vertices
[m_src_vertices
.size() - 2].y
);
84 m_spline_x
.add_point(3.0, m_src_vertices
[m_src_vertices
.size() - 1].x
);
85 m_spline_y
.add_point(3.0, m_src_vertices
[m_src_vertices
.size() - 1].y
);
89 m_spline_x
.init(m_src_vertices
.size());
90 m_spline_y
.init(m_src_vertices
.size());
93 for(i
= 0; i
< m_src_vertices
.size(); i
++)
95 double x
= m_closed
? i
+ 4 : i
;
96 m_spline_x
.add_point(x
, m_src_vertices
[i
].x
);
97 m_spline_y
.add_point(x
, m_src_vertices
[i
].y
);
100 m_max_abscissa
= m_src_vertices
.size() - 1;
103 m_cur_abscissa
= 4.0;
104 m_max_abscissa
+= 5.0;
105 m_spline_x
.add_point(m_src_vertices
.size() + 4, m_src_vertices
[0].x
);
106 m_spline_y
.add_point(m_src_vertices
.size() + 4, m_src_vertices
[0].y
);
107 m_spline_x
.add_point(m_src_vertices
.size() + 5, m_src_vertices
[1].x
);
108 m_spline_y
.add_point(m_src_vertices
.size() + 5, m_src_vertices
[1].y
);
109 m_spline_x
.add_point(m_src_vertices
.size() + 6, m_src_vertices
[2].x
);
110 m_spline_y
.add_point(m_src_vertices
.size() + 6, m_src_vertices
[2].y
);
111 m_spline_x
.add_point(m_src_vertices
.size() + 7, m_src_vertices
.next(2).x
);
112 m_spline_y
.add_point(m_src_vertices
.size() + 7, m_src_vertices
.next(2).y
);
114 m_spline_x
.prepare();
115 m_spline_y
.prepare();
125 //------------------------------------------------------------------------
126 unsigned vcgen_bspline::vertex(double* x
, double* y
)
128 unsigned cmd
= path_cmd_line_to
;
137 if(m_src_vertices
.size() < 2)
143 if(m_src_vertices
.size() == 2)
145 *x
= m_src_vertices
[m_src_vertex
].x
;
146 *y
= m_src_vertices
[m_src_vertex
].y
;
148 if(m_src_vertex
== 1) return path_cmd_move_to
;
149 if(m_src_vertex
== 2) return path_cmd_line_to
;
154 cmd
= path_cmd_move_to
;
159 if(m_cur_abscissa
>= m_max_abscissa
)
168 *x
= m_src_vertices
[m_src_vertices
.size() - 1].x
;
169 *y
= m_src_vertices
[m_src_vertices
.size() - 1].y
;
171 return path_cmd_line_to
;
175 *x
= m_spline_x
.get_stateful(m_cur_abscissa
);
176 *y
= m_spline_y
.get_stateful(m_cur_abscissa
);
178 m_cur_abscissa
+= m_interpolation_step
;
179 return (m_src_vertex
== 1) ? path_cmd_move_to
: path_cmd_line_to
;
183 return path_cmd_end_poly
| m_closed
;
186 return path_cmd_stop
;