~ubuntu-branches/ubuntu/lucid/agg/lucid-proposed

« back to all changes in this revision

Viewing changes to include/agg_vertex_sequence.h

  • Committer: Bazaar Package Importer
  • Author(s): Rene Engelhard
  • Date: 2005-11-29 02:02:41 UTC
  • Revision ID: james.westby@ubuntu.com-20051129020241-pmlxls0x6j2qv3nm
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//----------------------------------------------------------------------------
 
2
// Anti-Grain Geometry - Version 2.3
 
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_deque. The data is interpreted as a sequence of vertices.
 
31
    // It means that the type T must expose:
 
32
    //
 
33
    // bool 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_deque<T, S>
 
68
    {
 
69
    public:
 
70
        typedef pod_deque<T, S> base_type;
 
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
 
 
128
    // Coinciding points maximal distance (Epsilon)
 
129
    const double vertex_dist_epsilon = 1e-14;
 
130
 
 
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.
 
135
    struct vertex_dist
 
136
    {
 
137
        double   x;
 
138
        double   y;
 
139
        double   dist;
 
140
 
 
141
        vertex_dist() {}
 
142
        vertex_dist(double x_, double y_) :
 
143
            x(x_),
 
144
            y(y_),
 
145
            dist(0.0)
 
146
        {
 
147
        }
 
148
 
 
149
        bool operator () (const vertex_dist& val)
 
150
        {
 
151
            bool ret = (dist = calc_distance(x, y, val.x, val.y)) > vertex_dist_epsilon;
 
152
            if(!ret) dist = 1.0 / vertex_dist_epsilon;
 
153
            return ret;
 
154
        }
 
155
    };
 
156
 
 
157
 
 
158
 
 
159
    //--------------------------------------------------------vertex_dist_cmd
 
160
    // Save as the above but with additional "command" value
 
161
    struct vertex_dist_cmd : public vertex_dist
 
162
    {
 
163
        unsigned cmd;
 
164
 
 
165
        vertex_dist_cmd() {}
 
166
        vertex_dist_cmd(double x_, double y_, unsigned cmd_) :
 
167
            vertex_dist(x_, y_),
 
168
            cmd(cmd_)
 
169
        {
 
170
        }
 
171
    };
 
172
 
 
173
 
 
174
}
 
175
 
 
176
#endif