shithub: ballistics

Download patch

ref: 9090c1e8d2c462e217ab723c684f5a151295a0f6
parent: 44d868b0684ef88d830f2e99624b826fc4c3507e
author: rodri <[email protected]>
date: Wed Jan 17 09:15:37 EST 2024

make the scale adjustable. add knobs for most parameters.

--- a/dat.h
+++ b/dat.h
@@ -1,7 +1,6 @@
 #define Eg	9.81	/* earth's gravity (m·s⁻²) */
 #define Cd	0.45	/* drag coefficient for a sphere */
 #define ρ	1.293	/* air density (kg·m⁻³) */
-#define PIX2M	0.001
 #define M2PIX	(1.0/PIX2M)
 
 enum {
@@ -11,6 +10,7 @@
 	Sdrag,
 	Sdeltax,
 	Seta,
+	Sscale,
 	SLEN,
 };
 
--- a/main.c
+++ b/main.c
@@ -8,6 +8,8 @@
 #include "dat.h"
 #include "fns.h"
 
+double PIX2M = 5;
+
 Mousectl *mc;
 Keyboardctl *kc;
 Channel *scrsync;
@@ -56,7 +58,7 @@
 	ball.v = addpt2(ball.v, mulpt2(addpt2(Vec2(0,-Eg), divpt2(Fd, ball.mass)), Δt));
 	ball.p = addpt2(ball.p, mulpt2(ball.v, Δt));
 	snprint(stats[Spos], sizeof(stats[Spos]), "p: %v", ball.p);
-	snprint(stats[Sdrag], sizeof(stats[Sdrag]), "Fd: %v", Fd);
+	snprint(stats[Sdrag], sizeof(stats[Sdrag]), "Fd: %v", divpt2(Fd, ball.mass));
 	if(ball.p.y <= (2+1)*M2PIX){
 		ball.p.y = (2+1)*M2PIX;
 		ball.v = Vec2(0,0);
@@ -91,21 +93,49 @@
 {
 	enum {
 		SETV0,
+		SETPOS,
+		SETMASS,
+		SETDIAM,
 	};
 	static char *items[] = {
 	 [SETV0]	"set v0",
+	 [SETPOS]	"set position",
+	 [SETMASS]	"set mass",
+	 [SETDIAM]	"set diameter",
 		nil
 	};
 	static Menu menu = { .item = items };
-	char buf[32];
+	char buf[32], *p;
 
-	snprint(buf, sizeof(buf), "%g", v0);
 	switch(menuhit(2, mc, &menu, nil)){
 	case SETV0:
+		snprint(buf, sizeof(buf), "%g", v0);
 		enter("v0(m/s):", buf, sizeof(buf), mc, kc, nil);
 		if(buf[0] != 0)
 			v0 = strtod(buf, nil);
 		break;
+	case SETPOS:
+		snprint(buf, sizeof(buf), "%g, %g", ball.p.x, ball.p.y);
+		enter("pos(x,y):", buf, sizeof(buf), mc, kc, nil);
+		if(buf[0] != 0 && (p = strchr(buf, ',')) != nil){
+			ball.p.x = strtod(buf, nil);
+			ball.p.y = strtod(p+1, nil);
+		}
+		break;
+	case SETMASS:
+		snprint(buf, sizeof(buf), "%g", ball.mass);
+		enter("mass(kg):", buf, sizeof(buf), mc, kc, nil);
+		if(buf[0] != 0)
+			ball.mass = strtod(buf, nil);
+		break;
+	case SETDIAM:
+		snprint(buf, sizeof(buf), "%g", 2*ball.r);
+		enter("diameter(m):", buf, sizeof(buf), mc, kc, nil);
+		if(buf[0] != 0){
+			ball.r = strtod(buf, nil)/2;
+			A = 2*PI*ball.r*ball.r;	/* ½(4πr²) */
+		}
+		break;
 	}
 }
 
@@ -134,6 +164,24 @@
 }
 
 void
+zoomin(void)
+{
+	PIX2M += 0.01;
+	worldrf.bx = Vec2(PIX2M,0);
+	worldrf.by = Vec2(0,-PIX2M);
+	snprint(stats[Sscale], sizeof(stats[Sscale]), "s: %gm/pix", M2PIX);
+}
+
+void
+zoomout(void)
+{
+	PIX2M -= 0.01;
+	worldrf.bx = Vec2(PIX2M,0);
+	worldrf.by = Vec2(0,-PIX2M);
+	snprint(stats[Sscale], sizeof(stats[Sscale]), "s: %gm/px", M2PIX);
+}
+
+void
 mouse(void)
 {
 	Point2 p;
@@ -154,6 +202,10 @@
 		mmb();
 	if((mc->buttons & 4) != 0)
 		rmb();
+	if((mc->buttons & 8) != 0)
+		zoomin();
+	if((mc->buttons & 16) != 0)
+		zoomout();
 }
 
 void
@@ -215,6 +267,8 @@
 	if(statc == nil)
 		sysfatal("allocimage: %r");
 
+	snprint(stats[Sscale], sizeof(stats[Sscale]), "s: %gm/pix", M2PIX);
+
 	worldrf.p = Pt2(screen->r.min.x, screen->r.max.y, 1);
 	worldrf.bx = Vec2(PIX2M,0);
 	worldrf.by = Vec2(0,-PIX2M);
@@ -221,10 +275,10 @@
 
 	ball.p = Pt2((2+1)*M2PIX,(2+1)*M2PIX,1);
 	ball.v = Vec2(0, 0);
-	ball.mass = 106000;
-	ball.r = 0.1;		/* 10cm */
+	ball.mass = 0.149;
+	ball.r = 0.375;		/* 3.75cm */
 	A = 2*PI*ball.r*ball.r;	/* ½(4πr²) */
-	v0 = 1640; /* Paris Gun's specs */
+	v0 = 53.64;		/* avg baseball hit speed */
 
 	scrsync = chancreate(1, 0);
 	display->locking = 1;