Anti-Grain Geometry Tutorial
agg_vertex_sequence.h
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 // vertex_sequence container and vertex_dist struct
17 //
18 //----------------------------------------------------------------------------
19 #ifndef AGG_VERTEX_SEQUENCE_INCLUDED
20 #define AGG_VERTEX_SEQUENCE_INCLUDED
21 
22 #include "agg_basics.h"
23 #include "agg_array.h"
24 #include "agg_math.h"
25 
26 namespace agg
27 {
28 
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:
32  //
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:
42  //
43  // struct vertex_dist
44  // {
45  // double x;
46  // double y;
47  // double dist;
48  //
49  // vertex_dist() {}
50  // vertex_dist(double x_, double y_) :
51  // x(x_),
52  // y(y_),
53  // dist(0.0)
54  // {
55  // }
56  //
57  // bool operator () (const vertex_dist& val)
58  // {
59  // return (dist = calc_distance(x, y, val.x, val.y)) > EPSILON;
60  // }
61  // };
62  //
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>
68  {
69  public:
71 
72  void add(const T& val);
73  void modify_last(const T& val);
74  void close(bool remove_flag);
75  };
76 
77 
78 
79  //------------------------------------------------------------------------
80  template<class T, unsigned S>
81  void vertex_sequence<T, S>::add(const T& val)
82  {
83  if(base_type::size() > 1)
84  {
85  if(!(*this)[base_type::size() - 2]((*this)[base_type::size() - 1]))
86  {
87  base_type::remove_last();
88  }
89  }
90  base_type::add(val);
91  }
92 
93 
94  //------------------------------------------------------------------------
95  template<class T, unsigned S>
96  void vertex_sequence<T, S>::modify_last(const T& val)
97  {
98  base_type::remove_last();
99  add(val);
100  }
101 
102 
103 
104  //------------------------------------------------------------------------
105  template<class T, unsigned S>
106  void vertex_sequence<T, S>::close(bool closed)
107  {
108  while(base_type::size() > 1)
109  {
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);
114  }
115 
116  if(closed)
117  {
118  while(base_type::size() > 1)
119  {
120  if((*this)[base_type::size() - 1]((*this)[0])) break;
121  base_type::remove_last();
122  }
123  }
124  }
125 
126 
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
132  {
133  double x;
134  double y;
135  double dist;
136 
137  vertex_dist() {}
138  vertex_dist(double x_, double y_) :
139  x(x_),
140  y(y_),
141  dist(0.0)
142  {
143  }
144 
145  bool operator () (const vertex_dist& val)
146  {
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;
150  }
151  };
152 
153 
154 
155  //--------------------------------------------------------vertex_dist_cmd
156  // Save as the above but with additional "command" value
157  struct vertex_dist_cmd : public vertex_dist
158  {
159  unsigned cmd;
160 
161  vertex_dist_cmd() {}
162  vertex_dist_cmd(double x_, double y_, unsigned cmd_) :
163  vertex_dist(x_, y_),
164  cmd(cmd_)
165  {
166  }
167  };
168 
169 
170 }
171 
172 #endif
Definition: agg_arc.cpp:24