1
2//----------------------------------------------------------------------------
3// Anti-Grain Geometry - Version 2.3
4// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
5//
6// Permission to copy, use, modify, sell and distribute this software
7// is granted provided this copyright notice appears in all copies.
8// This software is provided "as is" without express or implied
9// warranty, and with no claim as to its suitability for any purpose.
10//
11//----------------------------------------------------------------------------
12// Contact: mcseem@antigrain.com
13//          mcseemagg@yahoo.com
14//          http://www.antigrain.com
15//----------------------------------------------------------------------------
16//
17// vertex_sequence container and vertex_dist struct
18//
19//----------------------------------------------------------------------------
20#ifndef AGG_VERTEX_SEQUENCE_INCLUDED
21#define AGG_VERTEX_SEQUENCE_INCLUDED
22#include "agg_basics.h"
23#include "agg_array.h"
24#include "agg_math.h"
25namespace agg
26{
27template<class T, unsigned S = 6>
28class vertex_sequence : public pod_deque<T, S>
29{
30public:
31    typedef pod_deque<T, S> base_type;
32    void add(const T& val);
33    void modify_last(const T& val);
34    void close(bool remove_flag);
35};
36template<class T, unsigned S>
37void vertex_sequence<T, S>::add(const T& val)
38{
39    if(base_type::size() > 1) {
40        if(!(*this)[base_type::size() - 2]((*this)[base_type::size() - 1])) {
41            base_type::remove_last();
42        }
43    }
44    base_type::add(val);
45}
46template<class T, unsigned S>
47void vertex_sequence<T, S>::modify_last(const T& val)
48{
49    base_type::remove_last();
50    add(val);
51}
52template<class T, unsigned S>
53void vertex_sequence<T, S>::close(bool closed)
54{
55    while(base_type::size() > 1) {
56        if((*this)[base_type::size() - 2]((*this)[base_type::size() - 1])) {
57            break;
58        }
59        T t = (*this)[base_type::size() - 1];
60        base_type::remove_last();
61        modify_last(t);
62    }
63    if(closed) {
64        while(base_type::size() > 1) {
65            if((*this)[base_type::size() - 1]((*this)[0])) {
66                break;
67            }
68            base_type::remove_last();
69        }
70    }
71}
72const FX_FLOAT vertex_dist_epsilon = 1e-14f;
73struct vertex_dist  {
74    FX_FLOAT   x;
75    FX_FLOAT   y;
76    FX_FLOAT   dist;
77    vertex_dist() {}
78    vertex_dist(FX_FLOAT x_, FX_FLOAT y_) :
79        x(x_),
80        y(y_),
81        dist(0)
82    {
83    }
84    bool operator () (const vertex_dist& val)
85    {
86        bool ret = (dist = calc_distance(x, y, val.x, val.y)) > vertex_dist_epsilon;
87        return ret;
88    }
89};
90struct vertex_dist_cmd : public vertex_dist {
91    unsigned cmd;
92    vertex_dist_cmd() {}
93    vertex_dist_cmd(FX_FLOAT x_, FX_FLOAT y_, unsigned cmd_) :
94        vertex_dist(x_, y_),
95        cmd(cmd_)
96    {
97    }
98};
99}
100#endif
101