diff options
Diffstat (limited to '')
-rw-r--r-- | src/toys/pwsbhandle.cpp | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/src/toys/pwsbhandle.cpp b/src/toys/pwsbhandle.cpp new file mode 100644 index 0000000..ce4f21e --- /dev/null +++ b/src/toys/pwsbhandle.cpp @@ -0,0 +1,77 @@ +class PWSBHandle : public Handle{ +public: + unsigned handles_per_curve, curve_size, segs; + PWSBHandle() {} + PWSBHandle(unsigned cs, unsigned segs) :handles_per_curve(cs*segs),curve_size(cs), segs(segs) {} + std::vector<Geom::Point> pts; + virtual void draw(cairo_t *cr, bool annotes = false); + + virtual void* hit(Geom::Point mouse); + virtual void move_to(void* hit, Geom::Point om, Geom::Point m); + void push_back(double x, double y) {pts.push_back(Geom::Point(x,y));} + Piecewise<SBasis> value(double y_0=150) { + Piecewise<SBasis> pws; + Point* base = &pts[0]; + for(unsigned i = 0; i < handles_per_curve; i+=curve_size) { + pws.push_cut(base[i][0]); + //Bad hack to move 0 to 150 + for(unsigned j = i; j < i + curve_size; j++) + base[j] = Point(base[j][0], base[j][1] - y_0); + pws.push_seg( Geom::handles_to_sbasis(base+i, curve_size-1)[1]); + for(unsigned j = i; j < i + curve_size; j++) + base[j] = Point(base[j][0], base[j][1] + y_0); + } + pws.push_cut(base[handles_per_curve - 1][0]); + assert(pws.invariants()); + return pws; + } + virtual void load(FILE* f); + virtual void save(FILE* f); +}; + +void PWSBHandle::draw(cairo_t *cr, bool /*annotes*/) { + for(auto & pt : pts) { + draw_circ(cr, pt); + } +} + +void* PWSBHandle::hit(Geom::Point mouse) { + for(auto & pt : pts) { + if(Geom::distance(mouse, pt) < 5) + return (void*)(&pt); + } + return 0; +} + +void PWSBHandle::move_to(void* hit, Geom::Point /*om*/, Geom::Point m) { + if(hit) { + *(Geom::Point*)hit = m; + Point* base = &pts[0]; + for(unsigned i = curve_size; i < handles_per_curve; i+=curve_size) { + base[i-1][0] = base[i][0]; + } + for(unsigned i = 0; i < handles_per_curve; i+=curve_size) { + for(unsigned j = 1; j < (curve_size-1); j++) { + double t = float(j)/(curve_size-1); + base[i+j][0] = (1 - t)*base[i][0] + t*base[i+curve_size-1][0]; + } + } + } +} + +void PWSBHandle::load(FILE* f) { + unsigned n = 0; + assert(3 == fscanf(f, "%d %d %d\n", &curve_size, &segs, &n)); + assert(n == curve_size*segs); + pts.clear(); + for(unsigned i = 0; i < n; i++) { + pts.push_back(read_point(f)); + } +} + +void PWSBHandle::save(FILE* f) { + fprintf(f, "%d %d %lu\n", curve_size, segs, pts.size()); + for(auto & pt : pts) { + fprintf(f, "%lf %lf\n", pt[0], pt[1]); + } +} |