btrfs: [] on the end of a struct field is a variable length array.
[haiku.git] / headers / libs / agg / agg_vertex_sequence.h
blob2ad0701b37a3e66b485f3d1892a298e07d0c8c70
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 //----------------------------------------------------------------------------
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"
24 #include "agg_math.h"
26 namespace agg
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)
34 //
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.
39 //
40 // The simple example is filtering coinciding vertices with calculation
41 // of the distance between the current and previous ones:
43 // struct vertex_dist
44 // {
45 // double x;
46 // double y;
47 // double dist;
49 // vertex_dist() {}
50 // vertex_dist(double x_, double y_) :
51 // x(x_),
52 // y(y_),
53 // dist(0.0)
54 // {
55 // }
57 // bool operator () (const vertex_dist& val)
58 // {
59 // return (dist = calc_distance(x, y, val.x, val.y)) > EPSILON;
60 // }
61 // };
63 // Function close() calls this operator and removes the last vertex if
64 // necessary.
65 //------------------------------------------------------------------------
66 template<class T, unsigned S=6>
67 class vertex_sequence : public pod_bvector<T, S>
69 public:
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();
90 base_type::add(val);
94 //------------------------------------------------------------------------
95 template<class T, unsigned S>
96 void vertex_sequence<T, S>::modify_last(const T& val)
98 base_type::remove_last();
99 add(val);
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();
113 modify_last(t);
116 if(closed)
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.
131 struct vertex_dist
133 double x;
134 double y;
135 double dist;
137 vertex_dist() {}
138 vertex_dist(double x_, double y_) :
139 x(x_),
140 y(y_),
141 dist(0.0)
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;
149 return ret;
155 //--------------------------------------------------------vertex_dist_cmd
156 // Save as the above but with additional "command" value
157 struct vertex_dist_cmd : public vertex_dist
159 unsigned cmd;
161 vertex_dist_cmd() {}
162 vertex_dist_cmd(double x_, double y_, unsigned cmd_) :
163 vertex_dist(x_, y_),
164 cmd(cmd_)
172 #endif