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

« back to all changes in this revision

Viewing changes to src/agg_vcgen_smooth_poly1.cpp

  • 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
// Smooth polygon generator
 
17
//
 
18
//----------------------------------------------------------------------------
 
19
 
 
20
#include "agg_vcgen_smooth_poly1.h"
 
21
 
 
22
namespace agg
 
23
{
 
24
 
 
25
    //------------------------------------------------------------------------
 
26
    vcgen_smooth_poly1::vcgen_smooth_poly1() :
 
27
        m_src_vertices(),
 
28
        m_smooth_value(0.5),
 
29
        m_closed(0),
 
30
        m_status(initial),
 
31
        m_src_vertex(0)
 
32
    {
 
33
    }
 
34
 
 
35
 
 
36
    //------------------------------------------------------------------------
 
37
    void vcgen_smooth_poly1::remove_all()
 
38
    {
 
39
        m_src_vertices.remove_all();
 
40
        m_closed = 0;
 
41
        m_status = initial;
 
42
    }
 
43
 
 
44
 
 
45
    //------------------------------------------------------------------------
 
46
    void vcgen_smooth_poly1::add_vertex(double x, double y, unsigned cmd)
 
47
    {
 
48
        m_status = initial;
 
49
        if(is_move_to(cmd))
 
50
        {
 
51
            m_src_vertices.modify_last(vertex_dist(x, y));
 
52
        }
 
53
        else
 
54
        {
 
55
            if(is_vertex(cmd))
 
56
            {
 
57
                m_src_vertices.add(vertex_dist(x, y));
 
58
            }
 
59
            else
 
60
            {
 
61
                m_closed = get_close_flag(cmd);
 
62
            }
 
63
        }
 
64
    }
 
65
 
 
66
 
 
67
    //------------------------------------------------------------------------
 
68
    void vcgen_smooth_poly1::rewind(unsigned)
 
69
    {
 
70
        if(m_status == initial)
 
71
        {
 
72
            m_src_vertices.close(m_closed != 0);
 
73
        }
 
74
        m_status = ready;
 
75
        m_src_vertex = 0;
 
76
    }
 
77
 
 
78
 
 
79
    //------------------------------------------------------------------------
 
80
    void vcgen_smooth_poly1::calculate(const vertex_dist& v0, 
 
81
                                       const vertex_dist& v1, 
 
82
                                       const vertex_dist& v2,
 
83
                                       const vertex_dist& v3)
 
84
    {
 
85
 
 
86
        double k1 = v0.dist / (v0.dist + v1.dist);
 
87
        double k2 = v1.dist / (v1.dist + v2.dist);
 
88
 
 
89
        double xm1 = v0.x + (v2.x - v0.x) * k1;
 
90
        double ym1 = v0.y + (v2.y - v0.y) * k1;
 
91
        double xm2 = v1.x + (v3.x - v1.x) * k2;
 
92
        double ym2 = v1.y + (v3.y - v1.y) * k2;
 
93
 
 
94
        m_ctrl1_x = v1.x + m_smooth_value * (v2.x - xm1);
 
95
        m_ctrl1_y = v1.y + m_smooth_value * (v2.y - ym1);
 
96
        m_ctrl2_x = v2.x + m_smooth_value * (v1.x - xm2);
 
97
        m_ctrl2_y = v2.y + m_smooth_value * (v1.y - ym2);
 
98
    }
 
99
 
 
100
 
 
101
    //------------------------------------------------------------------------
 
102
    unsigned vcgen_smooth_poly1::vertex(double* x, double* y)
 
103
    {
 
104
        unsigned cmd = path_cmd_line_to;
 
105
        while(!is_stop(cmd))
 
106
        {
 
107
            switch(m_status)
 
108
            {
 
109
            case initial:
 
110
                rewind(0);
 
111
 
 
112
            case ready:
 
113
                if(m_src_vertices.size() <  2)
 
114
                {
 
115
                    cmd = path_cmd_stop;
 
116
                    break;
 
117
                }
 
118
 
 
119
                if(m_src_vertices.size() == 2)
 
120
                {
 
121
                    *x = m_src_vertices[m_src_vertex].x;
 
122
                    *y = m_src_vertices[m_src_vertex].y;
 
123
                    m_src_vertex++;
 
124
                    if(m_src_vertex == 1) return path_cmd_move_to;
 
125
                    if(m_src_vertex == 2) return path_cmd_line_to;
 
126
                    cmd = path_cmd_stop;
 
127
                    break;
 
128
                }
 
129
 
 
130
                cmd = path_cmd_move_to;
 
131
                m_status = polygon;
 
132
                m_src_vertex = 0;
 
133
 
 
134
            case polygon:
 
135
                if(m_closed)
 
136
                {
 
137
                    if(m_src_vertex >= m_src_vertices.size())
 
138
                    {
 
139
                        *x = m_src_vertices[0].x;
 
140
                        *y = m_src_vertices[0].y;
 
141
                        m_status = end_poly;
 
142
                        return path_cmd_curve4;
 
143
                    }
 
144
                }
 
145
                else
 
146
                {
 
147
                    if(m_src_vertex >= m_src_vertices.size() - 1)
 
148
                    {
 
149
                        *x = m_src_vertices[m_src_vertices.size() - 1].x;
 
150
                        *y = m_src_vertices[m_src_vertices.size() - 1].y;
 
151
                        m_status = end_poly;
 
152
                        return path_cmd_curve3;
 
153
                    }
 
154
                }
 
155
 
 
156
                calculate(m_src_vertices.prev(m_src_vertex), 
 
157
                          m_src_vertices.curr(m_src_vertex), 
 
158
                          m_src_vertices.next(m_src_vertex),
 
159
                          m_src_vertices.next(m_src_vertex + 1));
 
160
 
 
161
                *x = m_src_vertices[m_src_vertex].x;
 
162
                *y = m_src_vertices[m_src_vertex].y;
 
163
                m_src_vertex++;
 
164
 
 
165
                if(m_closed)
 
166
                {
 
167
                    m_status = ctrl1;
 
168
                    return ((m_src_vertex == 1) ? 
 
169
                             path_cmd_move_to : 
 
170
                             path_cmd_curve4);
 
171
                }
 
172
                else
 
173
                {
 
174
                    if(m_src_vertex == 1)
 
175
                    {
 
176
                        m_status = ctrl_b;
 
177
                        return path_cmd_move_to;
 
178
                    }
 
179
                    if(m_src_vertex >= m_src_vertices.size() - 1)
 
180
                    {
 
181
                        m_status = ctrl_e;
 
182
                        return path_cmd_curve3;
 
183
                    }
 
184
                    m_status = ctrl1;
 
185
                    return path_cmd_curve4;
 
186
                }
 
187
                break;
 
188
 
 
189
            case ctrl_b:
 
190
                *x = m_ctrl2_x;
 
191
                *y = m_ctrl2_y;
 
192
                m_status = polygon;
 
193
                return path_cmd_curve3;
 
194
 
 
195
            case ctrl_e:
 
196
                *x = m_ctrl1_x;
 
197
                *y = m_ctrl1_y;
 
198
                m_status = polygon;
 
199
                return path_cmd_curve3;
 
200
 
 
201
            case ctrl1:
 
202
                *x = m_ctrl1_x;
 
203
                *y = m_ctrl1_y;
 
204
                m_status = ctrl2;
 
205
                return path_cmd_curve4;
 
206
 
 
207
            case ctrl2:
 
208
                *x = m_ctrl2_x;
 
209
                *y = m_ctrl2_y;
 
210
                m_status = polygon;
 
211
                return path_cmd_curve4;
 
212
 
 
213
            case end_poly:
 
214
                m_status = stop;
 
215
                return path_cmd_end_poly | m_closed;
 
216
 
 
217
            case stop:
 
218
                return path_cmd_stop;
 
219
            }
 
220
        }
 
221
        return cmd;
 
222
    }
 
223
 
 
224
}
 
225