summaryrefslogtreecommitdiffstats
path: root/src/toys/pwsbhandle.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/toys/pwsbhandle.cpp77
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]);
+ }
+}