1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
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 // vertex_sequence container and vertex_dist struct
18 //----------------------------------------------------------------------------
19 #ifndef AGG_VERTEX_SEQUENCE_INCLUDED
20 #define AGG_VERTEX_SEQUENCE_INCLUDED
22 #include "agg_basics.h"
23 #include "agg_array.h"
29 //----------------------------------------------------------vertex_sequence
30 // Modified agg::pod_bvector. The data is interpreted as a sequence
31 // of vertices. It means that the type T must expose:
33 // bool T::operator() (const T& val)
35 // that is called every time new vertex is being added. The main purpose
36 // of this operator is the possibility to calculate some values during
37 // adding and to return true if the vertex fits some criteria or false if
38 // it doesn't. In the last case the new vertex is not added.
40 // The simple example is filtering coinciding vertices with calculation
41 // of the distance between the current and previous ones:
50 // vertex_dist(double x_, double y_) :
57 // bool operator () (const vertex_dist& val)
59 // return (dist = calc_distance(x, y, val.x, val.y)) > EPSILON;
63 // Function close() calls this operator and removes the last vertex if
65 //------------------------------------------------------------------------
66 template<class T
, unsigned S
=6>
67 class vertex_sequence
: public pod_bvector
<T
, S
>
70 typedef pod_bvector
<T
, S
> base_type
;
72 void add(const T
& val
);
73 void modify_last(const T
& val
);
74 void close(bool remove_flag
);
79 //------------------------------------------------------------------------
80 template<class T
, unsigned S
>
81 void vertex_sequence
<T
, S
>::add(const T
& val
)
83 if(base_type::size() > 1)
85 if(!(*this)[base_type::size() - 2]((*this)[base_type::size() - 1]))
87 base_type::remove_last();
94 //------------------------------------------------------------------------
95 template<class T
, unsigned S
>
96 void vertex_sequence
<T
, S
>::modify_last(const T
& val
)
98 base_type::remove_last();
104 //------------------------------------------------------------------------
105 template<class T
, unsigned S
>
106 void vertex_sequence
<T
, S
>::close(bool closed
)
108 while(base_type::size() > 1)
110 if((*this)[base_type::size() - 2]((*this)[base_type::size() - 1])) break;
111 T t
= (*this)[base_type::size() - 1];
112 base_type::remove_last();
118 while(base_type::size() > 1)
120 if((*this)[base_type::size() - 1]((*this)[0])) break;
121 base_type::remove_last();
127 //-------------------------------------------------------------vertex_dist
128 // Vertex (x, y) with the distance to the next one. The last vertex has
129 // distance between the last and the first points if the polygon is closed
130 // and 0.0 if it's a polyline.
138 vertex_dist(double x_
, double y_
) :
145 bool operator () (const vertex_dist
& val
)
147 bool ret
= (dist
= calc_distance(x
, y
, val
.x
, val
.y
)) > vertex_dist_epsilon
;
148 if(!ret
) dist
= 1.0 / vertex_dist_epsilon
;
155 //--------------------------------------------------------vertex_dist_cmd
156 // Save as the above but with additional "command" value
157 struct vertex_dist_cmd
: public vertex_dist
162 vertex_dist_cmd(double x_
, double y_
, unsigned cmd_
) :