From 9090c1e8d2c462e217ab723c684f5a151295a0f6 Mon Sep 17 00:00:00 2001 From: rodri Date: Wed, 17 Jan 2024 14:15:37 +0000 Subject: make the scale adjustable. add knobs for most parameters. --- dat.h | 2 +- main.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 61 insertions(+), 7 deletions(-) diff --git a/dat.h b/dat.h index da2038d..e3145b5 100644 --- 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 @@ enum { Sdrag, Sdeltax, Seta, + Sscale, SLEN, }; diff --git a/main.c b/main.c index 42fbaf8..70c30a0 100644 --- 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 @@ void 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 @@ mmb(void) { 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; } } @@ -133,6 +163,24 @@ rmb(void) } } +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) { @@ -154,6 +202,10 @@ mouse(void) mmb(); if((mc->buttons & 4) != 0) rmb(); + if((mc->buttons & 8) != 0) + zoomin(); + if((mc->buttons & 16) != 0) + zoomout(); } void @@ -215,16 +267,18 @@ threadmain(int argc, char *argv[]) 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); 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; -- cgit v1.2.3