shithub: musw

Download patch

ref: b63b8b0e316fa4b8d4362cb2e538bf5d8a75552a
parent: c492170716830326376e3a612f685df88f753621
author: rodri <rgl@antares-labs.eu>
date: Tue Apr 25 00:27:22 EDT 2023

show a guide when rotating the vmodel object.

--- a/vmodeled/main.c
+++ b/vmodeled/main.c
@@ -13,6 +13,12 @@
 	NStrokes
 } Stroke;
 
+typedef enum {
+	Drawing,
+	Zooming,
+	Rotating
+} State;
+
 /*
  * Vector model - made out of lines and curves
  */
@@ -47,10 +53,11 @@
 RFrame worldrf;
 Object mainobj;
 Stroke stroke;
+State curstate;
 Point2 ptstk[3];
 Point2 *ptstkp;
 char *vmdlfile;
-Image *ptselcol;
+Image *ptselcol, *guidecol;
 
 void resized(void);
 
@@ -257,7 +264,7 @@
 
 	while(sp-- > ptstk){
 		pt = toscreen(invrframexform(*sp, mainobj));
-		fillellipse(screen, pt, 2, 2, ptselcol, ZP);
+		fillellipse(screen, pt, 2, 2, guidecol, ZP);
 		draw(screen, rectaddpt(Rect(0,0,1,1), pt), display->black, nil, ZP);
 	}
 }
@@ -278,6 +285,34 @@
 }
 
 void
+drawguides(void)
+{
+	Point p, hingepts[3];
+	Point2 hinge[3];
+	char buf[128];
+	double θ;
+	int i;
+
+	if(curstate == Rotating){
+		hinge[2] = Pt2(1,0,1);
+		hinge[2] = invrframexform(hinge[2], mainobj);
+		θ = atan2(hinge[2].y, hinge[2].x);
+		hinge[0] = Vec2(1,0);
+		hinge[2] = normvec2(Vec2(hinge[2].x,hinge[2].y));
+		hinge[1] = normvec2(divpt2(addpt2(hinge[0], hinge[2]), 2));
+
+		line(screen, toscreen(Pt2(0,0,1)), toscreen(addpt2(Pt2(0,0,1), mulpt2(hinge[2], 50))), 0, 0, 0, guidecol, ZP);
+		for(i = 0; i < nelem(hinge); i++)
+			hingepts[i] = toscreen(addpt2(Pt2(0,0,1), mulpt2(hinge[i], i&1? 25: 20)));
+		bezspline(screen, hingepts, nelem(hingepts), 0, 0, 0, guidecol, ZP);
+
+		p = toscreen(addpt2(Pt2(0,0,1), mulpt2(hinge[1], 50)));
+		snprint(buf, sizeof buf, "%g°", θ/DEG);
+		string(screen, p, guidecol, ZP, font, buf);
+	}
+}
+
+void
 redraw(void)
 {
 	lockdisplay(display);
@@ -285,6 +320,7 @@
 	drawaxes();
 	drawvmodel(screen, mainobj.mdl);
 	drawstrokepts();
+	drawguides();
 	drawinfo();
 	flushimage(display, 1);
 	unlockdisplay(display);
@@ -390,6 +426,7 @@
 	double z; /* zooming factor */
 	Point oldxy, Δxy;
 
+	curstate = Zooming;
 	oldxy = mc->xy;
 
 	for(;;){
@@ -402,6 +439,7 @@
 		oldxy = mc->xy;
 		redraw();
 	}
+	curstate = Drawing;
 }
 
 void
@@ -410,6 +448,7 @@
 	Point2 p;
 	double oldθ, θ;
 
+	curstate = Rotating;
 	p = rframexform(fromscreen(mc->xy), mainobj);
 	oldθ = atan2(p.y, p.x);
 
@@ -422,6 +461,7 @@
 		mainobj.rotate(&mainobj, θ);
 		redraw();
 	}
+	curstate = Drawing;
 }
 
 void
@@ -485,7 +525,7 @@
 
 	if(newwindow(nil) < 0)
 		sysfatal("newwindow: %r");
-	if(initdraw(nil, nil, nil) < 0)
+	if(initdraw(nil, nil, "vmodeled") < 0)
 		sysfatal("initdraw: %r");
 	if((mc = initmouse(nil, screen)) == nil)
 		sysfatal("initmouse: %r");
@@ -507,6 +547,7 @@
 	ptstkp = &ptstk[0];
 
 	ptselcol = eallocimage(display, Rect(0,0,1,1), screen->chan, 1, DYellow);
+	guidecol = eallocimage(display, Rect(0,0,1,1), screen->chan, 1, DPalebluegreen);
 
 	display->locking = 1;
 	unlockdisplay(display);