From b3822385045bb11446f479afb67733ff21c77823 Mon Sep 17 00:00:00 2001 From: rodri Date: Tue, 12 May 2020 10:48:16 +0000 Subject: new toy: bsplines --- bsplines.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mkfile | 1 + 2 files changed, 139 insertions(+) create mode 100644 bsplines.c diff --git a/bsplines.c b/bsplines.c new file mode 100644 index 0000000..8abb53a --- /dev/null +++ b/bsplines.c @@ -0,0 +1,138 @@ +#include +#include +#include +#include +#include + +typedef struct Point2 Point2; +typedef struct Bspline Bspline; + +struct Point2 +{ + double x, y, w; +}; + +struct Bspline +{ + Point2 *pts; + ulong npt; +}; + +enum { + Cbg, + Cctl, + Cbez, + NCOLOR +}; + +Image *pal[NCOLOR]; +Bspline *bsplines; +Point2 *pts; +ulong nbspline, npt; + +Point2 +Pt2(double x, double y, double w) +{ + return (Point2){x,y,w}; +} + +Point +toscreen(Point2 p) +{ + return addpt(screen->r.min, Pt(p.x,p.y)); +} + +Point2 +fromscreen(Point p) +{ + p = subpt(p, screen->r.min); + return Pt2(p.x,p.y,1); +} + +void +initpalette(void) +{ + pal[Cbg] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x000000ff); + pal[Cctl] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x00ff00ff); + pal[Cbez] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xff0000ff); +} + +void +redraw(void) +{ + Point *bpts; + int i, j; + + draw(screen, screen->r, pal[Cbg], nil, ZP); + for(i = 0; i < nbspline; i++){ + bpts = malloc(bsplines[i].npt*sizeof(Point)); + for(j = 0; j < bsplines[i].npt; j++) + bpts[j] = toscreen(bsplines[i].pts[j]); + bezspline(screen, bpts, bsplines[i].npt, Endsquare, Endsquare, 0, pal[Cbez], ZP); + free(bpts); + } + for(i = 0; i < npt; i++) + fillellipse(screen, toscreen(pts[i]), 2, 2, pal[Cctl], ZP); + flushimage(display, 1); +} + +void +usage(void) +{ + fprint(2, "usage: %s\n", argv0); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + Event e; + Bspline b; + + ARGBEGIN{ + default: usage(); + }ARGEND; + if(argc > 0) + usage(); + if(initdraw(nil, nil, nil) < 0) + sysfatal("initdraw: %r"); + initpalette(); + einit(Emouse|Ekeyboard); + redraw(); + for(;;) + switch(event(&e)){ + case Emouse: + if((e.mouse.buttons&1) != 0){ + pts = realloc(pts, ++npt*sizeof(Point2)); + pts[npt-1] = fromscreen(e.mouse.xy); + redraw(); + } + if((e.mouse.buttons&4) != 0){ + if(npt > 1){ + b.pts = pts; + b.npt = npt; + bsplines = realloc(bsplines, ++nbspline*sizeof(Bspline)); + bsplines[nbspline-1] = b; + pts = nil; + npt = 0; + } + redraw(); + } + break; + case Ekeyboard: + switch(e.kbdc){ + case 'q': + case Kdel: + exits(0); + } + break; + } +} + +void +eresized(int) +{ + if(getwindow(display, Refnone) < 0) + sysfatal("resize failed"); + redraw(); +} diff --git a/mkfile b/mkfile index 896b94c..3d849bb 100644 --- a/mkfile +++ b/mkfile @@ -4,5 +4,6 @@ BIN=/$objtype/bin/etoys TARG=\ triangles\ beziers\ + bsplines\