3
* Copyright (C) Remigiusz Dybka 2009 <remigiusz.dybka@gmail.com>
5
Zaz is free software: you can redistribute it and/or modify it
6
under the terms of the GNU General Public License as published by the
7
Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
10
Zaz is distributed in the hope that it will be useful, but
11
WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
See the GNU General Public License for more details.
15
You should have received a copy of the GNU General Public License along
16
with this program. If not, see <http://www.gnu.org/licenses/>.
21
#define MIDP(a, b, t) XY(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t)
23
std::vector<XY> Bezier::Generate(int steps)
25
double stepping = 1.0 / (double)steps;
28
std::vector<BezierPoint>::iterator iter;
29
std::vector<BezierPoint>::iterator iter2;
32
for (iter = points.begin(), iter2 = points.begin(), ++iter2; iter2 != points.end(); ++iter, ++iter2)
34
XY p0(iter->x, iter->y);
35
XY p1(iter->cx, iter->cy);
36
XY p2(iter2->cx, iter2->cy);
37
XY p3(iter2->x, iter2->y);
39
// if not first point, the controls for in p1 are inverse
43
p1 = XY((iter->x - iter->cx) + iter->x,
44
(iter->y - iter->cy) + iter->y);
48
for (double t = 0; t < 1.0; t+= stepping)
50
XY l1 = MIDP(p0, p1, t);
51
XY l2 = MIDP(p1, p2, t);
52
XY l3 = MIDP(p2, p3, t);
54
XY m1 = MIDP(l1, l2, t);
55
XY m2 = MIDP(l2, l3, t);
57
ret.push_back(MIDP(m1, m2, t));
60
ret.push_back(XY(iter2->x, iter2->y));
66
double veclen(XY a, XY b)
68
return sqrt(pow(fabs(b.x - a.x), 2.0) + pow(fabs(b.y - a.y), 2.0));
71
std::vector<XY> Bezier::GenerateUniform(double step)
74
std::vector<BezierPoint>::iterator iter;
75
std::vector<BezierPoint>::iterator iter2;
78
for (iter = points.begin(), iter2 = points.begin(), ++iter2; iter2 != points.end(); ++iter, ++iter2)
80
XY p0(iter->x, iter->y);
81
XY p1(iter->cx, iter->cy);
82
XY p2(iter2->cx, iter2->cy);
83
XY p3(iter2->x, iter2->y);
85
// if not first point, the controls for in p1 are inverse
88
p1 = XY((iter->x - iter->cx) + iter->x,
89
(iter->y - iter->cy) + iter->y);
94
double stepping = 0.01 / (((veclen(p1, p0) +
96
veclen(p3, p2)) / 3.0) / step);
99
for (double t = 0; t < 1.0; t+= stepping)
101
XY l1 = MIDP(p0, p1, t);
102
XY l2 = MIDP(p1, p2, t);
103
XY l3 = MIDP(p2, p3, t);
105
XY m1 = MIDP(l1, l2, t);
106
XY m2 = MIDP(l2, l3, t);
108
XY np = MIDP(m1, m2, t);
110
double len = veclen(np, lp);
118
ret.push_back(XY(iter2->x, iter2->y));
124
std::vector<XY> Bezier::GenerateBalls(double dist, int steps)
127
std::vector<BezierPoint>::iterator iter;
128
std::vector<BezierPoint>::iterator iter2;
131
bool firstDist = true;
133
for (iter = points.begin(), iter2 = points.begin(), ++iter2; iter2 != points.end(); ++iter, ++iter2)
135
XY p0(iter->x, iter->y);
136
XY p1(iter->cx, iter->cy);
137
XY p2(iter2->cx, iter2->cy);
138
XY p3(iter2->x, iter2->y);
140
// if not first point, the controls for in p1 are inverse
143
p1 = XY((iter->x - iter->cx) + iter->x,
144
(iter->y - iter->cy) + iter->y);
149
double step = dist / (double)steps;
150
double stepping = 0.01 / (((veclen(p1, p0) +
152
veclen(p3, p2)) / 3.0) / step);
157
for (double t = 0; t < 1.0; t+= stepping)
159
XY l1 = MIDP(p0, p1, t);
160
XY l2 = MIDP(p1, p2, t);
161
XY l3 = MIDP(p2, p3, t);
163
XY m1 = MIDP(l1, l2, t);
164
XY m2 = MIDP(l2, l3, t);
166
XY np = MIDP(m1, m2, t);
168
if ((firstDist) && (s <= dist * steps))
170
if (veclen(lp, np) >= step)
179
double len = veclen(np, ret[s - steps]);
191
ret.push_back(XY(iter2->x, iter2->y));