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
// 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_deque. The data is interpreted as a sequence of vertices.
31
// It means that the type T must expose:
33
// bool 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_deque<T, S>
70
typedef pod_deque<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();
128
// Coinciding points maximal distance (Epsilon)
129
const double vertex_dist_epsilon = 1e-14;
131
//-------------------------------------------------------------vertex_dist
132
// Vertex (x, y) with the distance to the next one. The last vertex has
133
// distance between the last and the first points if the polygon is closed
134
// and 0.0 if it's a polyline.
142
vertex_dist(double x_, double y_) :
149
bool operator () (const vertex_dist& val)
151
bool ret = (dist = calc_distance(x, y, val.x, val.y)) > vertex_dist_epsilon;
152
if(!ret) dist = 1.0 / vertex_dist_epsilon;
159
//--------------------------------------------------------vertex_dist_cmd
160
// Save as the above but with additional "command" value
161
struct vertex_dist_cmd : public vertex_dist
166
vertex_dist_cmd(double x_, double y_, unsigned cmd_) :