2
#include "cubic_bez_util.h"
6
Maybe<Rect> Path::bbox() const {
7
// needs work for other elements.
8
if(handles.size() > 0) {
9
Rect r(handles[0], handles[0]);
11
for(std::vector<Geom::Point>::const_iterator h(handles.begin()), e(handles.end());
15
return Maybe<Rect>(r);
22
* note that this operation modifies the path.
25
void Path::push_back(PathElem e) {
26
assert(e.begin() != e.end());
27
if(!handles.empty() && *e.begin() != handles.back()) {
28
cmd.push_back(Geom::moveto);
29
handles.push_back(*e.begin());
34
handles.insert(handles.end(), e.begin(), e.end());
36
handles.insert(handles.end(), e.begin()+1, e.end());
41
* copy elements from [s,e) to before before (as per vector.insert)
42
* note that this operation modifies the path.
45
void Path::insert(PathConstIter before, PathConstIter s, PathConstIter e) {
48
if((*s).begin()[0] != ) {
49
cmd.push_back(Geom::moveto);
50
handles.push_back(*e.begin());
53
handles.insert(handles.end(), e.begin(), e.end());
58
/*Path Path::insert_node(PathLocation at) {
61
p.insert(p.end(), begin(), at.it); // begining of path
64
Geom::Point Geom::Path::PathElem::point_at(double t) {
66
case Geom::moveto: // these four could be merged by a smarter person
69
return Lerp(t, s[0], s[1]);
73
for(int i = 0; i < 2; i++)
74
mid[i] = Lerp(t, s[i], s[i+1]);
75
return Lerp(t, mid[0], mid[1]);
80
for(int i = 0; i < 3; i++)
81
mid[i] = Lerp(t, s[i], s[i+1]);
82
Geom::Point midmid[2];
83
for(int i = 0; i < 2; i++)
84
midmid[i] = Lerp(t, mid[i], mid[i+1]);
85
return Lerp(t, midmid[0], midmid[1]);
93
Geom::Path::PathElem::point_tangent_acc_at(double t,
98
case Geom::moveto: // these four could be merged by a smarter person
102
pos = Lerp(t, s[0], s[1]);
109
for(int i = 0; i < 2; i++)
110
mid[i] = Lerp(t, s[i], s[i+1]);
111
pos = Lerp(t, mid[0], mid[1]);
117
for(int i = 0; i < 4; i++)
120
cubic_bezier_poly_coeff(s, pc);
121
pos = t*t*t*pc[3] + t*t*pc[2] + t*pc[1] + pc[0];
122
tgt = 3*t*t*pc[3] + 2*t*pc[2] + pc[1];
123
acc = 6*t*pc[3] + 2*pc[2];
132
Point Path::point_at(PathLocation at) {
133
return (*at.it).point_at(at.t);
136
void Path::point_tangent_acc_at(PathLocation at, Point &pos, Point & tgt, Point &acc) {
137
(*at.it).point_tangent_acc_at(at.t, pos, tgt, acc);
140
#include "nearestpoint.cpp"
142
bool Path::PathElem::nearest_location(Point p, double& dist, double& tt) {
143
double new_dist, new_t;
146
new_dist = L2(p - s[0]);
147
new_t = 0; // not meaningful
149
// For the rest we can assume that start has already been tried.
152
new_dist = L2(p - s[1]);
154
double t = dot(p - s[0], (s[1] - s[0])) / dot(s[1] - s[0], s[1] - s[0]);
155
if((t > 0) && (t < 1)) {
157
new_dist = fabs(dot(p - s[0], unit_vector(rot90(s[1] - s[0]))));
164
for(int i = 0; i < 4; i++)
165
hnd[i] = (*this)[i];// fixme
166
new_t = NearestPointOnCurve(p, hnd);
167
new_dist = L2(p - point_at(new_t));
173
if(new_dist < dist) {
181
Path::PathLocation Path::nearest_location(Point p, double &dist) {
182
PathLocation pl(begin(), 0);
186
for(PathConstIter elm = begin();
190
if((*elm).nearest_location(p, dist, t)) {
191
pl = PathLocation(elm, t);
198
Path Path::subpath(PathConstIter begin, PathConstIter end) {
200
for(PathConstIter iter(begin); iter != end; ++iter) {
201
result.push_back(*iter);
211
int main(int argc, char **argv) {
220
c-file-style:"stroustrup"
221
c-file-offsets:((innamespace . 0)(substatement-open . 0))
226
vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :