shithub: ballistics

Download patch

ref: d6be49085c76bbea87b7d7c61455b93883669bf1
parent: 168a16b70a928ed64061bdac7fc9d52235c3f9fc
author: rodri <rgl@antares-labs.eu>
date: Tue Jan 16 12:09:14 EST 2024

rewrite it using libgeometry.

--- a/dat.h
+++ b/dat.h
@@ -1,15 +1,8 @@
-#define DEG	0.01745329251994330
 #define Eg	9.81
 #define PIX2M	0.001
 #define M2PIX	(1.0/PIX2M)
 
 enum {
-	STACK = 8192,
-	SEC = 1000,
-	FPS = 60,
-};
-
-enum {
 	Stheta = 0,
 	Spos,
 	Svel,
@@ -18,15 +11,10 @@
 	SLEN,
 };
 
-typedef struct Vector Vector;
-typedef double Matrix[3][3];
 typedef struct Projectile Projectile;
 
-struct Vector {
-	double x, y, w;
-};
-
-struct Projectile {
-	Vector p, v;
+struct Projectile
+{
+	Point2 p, v;
 	double mass;
 };
--- a/fns.h
+++ b/fns.h
@@ -1,15 +1,3 @@
-void addm(Matrix, Matrix);
-void subm(Matrix, Matrix);
-void mulm(Matrix, Matrix);
-void transm(Matrix);
-double detm(Matrix);
-Vector mulvecm(Vector, Matrix);
-Vector Vec(double, double, double);
-Vector addvec(Vector, Vector);
-Vector subvec(Vector, Vector);
-Vector mulvec(Vector, double);
-double dotvec(Vector, Vector);
-Vector normvec(Vector);
-double round(double);
-double hypot3(double, double, double);
+#define HZ2MS(hz)	(1000/(hz))
+
 void *emalloc(ulong);
--- a/main.c
+++ b/main.c
@@ -4,6 +4,7 @@
 #include <draw.h>
 #include <mouse.h>
 #include <keyboard.h>
+#include <geometry.h>
 #include "dat.h"
 #include "fns.h"
 
@@ -10,12 +11,11 @@
 Mousectl *mc;
 Keyboardctl *kc;
 Channel *scrsync;
-Point orig;
-Vector basis;
+RFrame worldrf;
 Projectile ball;
 double t0, Δt;
 double v0;
-Vector target;
+Point2 target;
 
 char stats[SLEN][64];
 Image *statc;
@@ -34,15 +34,16 @@
 }
 
 Point
-toscreen(Vector p)
+toscreen(Point2 p)
 {
-	return addpt(orig, Pt(p.x*basis.x, p.y*basis.y));
+	p = invrframexform(p, worldrf);
+	return Pt(p.x, p.y);
 }
 
-Vector
+Point2
 fromscreen(Point p)
 {
-	return Vec((p.x-screen->r.min.x)*M2PIX, (screen->r.max.y-p.y)*M2PIX, 1);
+	return rframexform(Pt2(p.x, p.y, 1), worldrf);
 }
 
 void
@@ -50,7 +51,7 @@
 {
 	int i;
 
-	snprint(stats[Svel], sizeof(stats[Svel]), "v: %gm/s", hypot(ball.v.x, ball.v.y));
+	snprint(stats[Svel], sizeof(stats[Svel]), "v: %gm/s", vec2len(ball.v));
 	snprint(stats[Sdeltax], sizeof(stats[Sdeltax]), "Δx: %gm", target.x-ball.p.x);
 	for(i = 0; i < nelem(stats); i++)
 		stringn(screen, addpt(screen->r.min, Pt(10, font->height*i+1)), statc, ZP, font, stats[i], sizeof(stats[i]));
@@ -62,7 +63,7 @@
 	lockdisplay(display);
 	draw(screen, screen->r, display->black, nil, ZP);
 	fillellipse(screen, toscreen(ball.p), 2, 2, display->white, ZP);
-	line(screen, toscreen(Vec(ball.p.x, 0, 1)), toscreen(target), 0, 0, 1, statc, ZP);
+	line(screen, toscreen(Pt2(ball.p.x, 0, 1)), toscreen(target), 0, 0, 1, statc, ZP);
 	drawstats();
 	flushimage(display, 1);
 	unlockdisplay(display);
@@ -106,8 +107,8 @@
 
 	switch(menuhit(3, mc, &menu, nil)){
 	case RST:
-		ball.p = Vec((2+1)*M2PIX, (2+1)*M2PIX, 1);
-		ball.v = Vec(0, 0, 1);
+		ball.p = Pt2((2+1)*M2PIX,(2+1)*M2PIX,1);
+		ball.v = Vec2(0,0);
 		break;
 	case QUIT:
 		threadexitsall(nil);
@@ -117,19 +118,19 @@
 void
 mouse(void)
 {
-	Vector p;
+	Point2 p;
 	double θ, dist, eta;
 
 	if(ball.p.y <= (2+1)*M2PIX){
-		p = subvec(fromscreen(mc->xy), ball.p);
+		p = subpt2(fromscreen(mc->xy), ball.p);
 		θ = atan2(p.y, p.x);
 		snprint(stats[Stheta], sizeof(stats[Stheta]), "θ: %g°", θ*180/PI);
 		dist = v0*v0*sin(2*θ)/Eg;
-		target = Vec(ball.p.x+dist, 0, 1);
+		target = Pt2(ball.p.x+dist, 0, 1);
 		eta = 2*v0*sin(θ)/Eg;
 		snprint(stats[Seta], sizeof(stats[Seta]), "eta: %gs", eta);
 		if((mc->buttons & 1) != 0)
-			ball.v = Vec(v0*cos(θ), v0*sin(θ), 1);
+			ball.v = Vec2(v0*cos(θ), v0*sin(θ));
 	}
 	if((mc->buttons & 2) != 0)
 		mmb();
@@ -153,7 +154,7 @@
 	lockdisplay(display);
 	if(getwindow(display, Refnone) < 0)
 		fprint(2, "can't reattach to window\n");
-	orig = Pt(screen->r.min.x, screen->r.max.y);
+	worldrf.p = Pt2(screen->r.min.x, screen->r.max.y, 1);
 	unlockdisplay(display);
 	redraw();
 }
@@ -163,20 +164,10 @@
 {
 	for(;;){
 		send(scrsync, nil);
-		sleep(SEC/FPS);
+		sleep(HZ2MS(60));
 	}
 }
 
-#pragma varargck type "V" Vector;
-int
-Vfmt(Fmt *f)
-{
-	Vector v;
-
-	v = va_arg(f->args, Vector);
-	return fmtprint(f, "(%g %g)", v.x, v.y);
-}
-
 void
 usage(void)
 {
@@ -189,7 +180,7 @@
 {
 	Rune r;
 
-	fmtinstall('V', Vfmt);
+	GEOMfmtinstall();
 	ARGBEGIN{
 	default: usage();
 	}ARGEND;
@@ -205,18 +196,23 @@
 	statc = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, DYellow);
 	if(statc == nil)
 		sysfatal("allocimage: %r");
-	orig = Pt(screen->r.min.x, screen->r.max.y);
-	basis = Vec(PIX2M, -PIX2M, 1);
-	ball.p = Vec((2+1)*M2PIX, (2+1)*M2PIX, 1);
-	ball.v = Vec(0, 0, 1);
+
+	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;
 	v0 = 1640; /* Paris Gun's specs */
+
 	scrsync = chancreate(1, 0);
 	display->locking = 1;
 	unlockdisplay(display);
-	proccreate(scrsyncproc, 0, STACK);
-	t0 = nsec();
 
+	proccreate(scrsyncproc, 0, mainstacksize);
+
+	t0 = nsec();
 	for(;;){
 		Alt a[] = {
 			{mc->c, &mc->Mouse, CHANRCV},
@@ -232,12 +228,12 @@
 		case 3: redraw(); break;
 		}
 		Δt = (nsec()-t0)/1e9;
-		ball.v = addvec(ball.v, mulvec(Vec(0, -Eg, 1), Δt));
-		ball.p = addvec(ball.p, mulvec(ball.v, Δt));
-		snprint(stats[Spos], sizeof(stats[Spos]), "p: %V", ball.p);
+		ball.v = addpt2(ball.v, mulpt2(Vec2(0,-Eg), Δt));
+		ball.p = addpt2(ball.p, mulpt2(ball.v, Δt));
+		snprint(stats[Spos], sizeof(stats[Spos]), "p: %v", ball.p);
 		if(ball.p.y <= (2+1)*M2PIX){
 			ball.p.y = (2+1)*M2PIX;
-			ball.v = Vec(0, 0, 1);
+			ball.v = Vec2(0,0);
 		}
 		t0 += Δt*1e9;
 	}
--- a/matrix.c
+++ /dev/null
@@ -1,74 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include "dat.h"
-#include "fns.h"
-
-void
-addm(Matrix a, Matrix b)
-{
-	int i, j;
-
-	for(i = 0; i < 3; i++)
-		for(j = 0; j < 3; j++)
-			a[i][j] += b[i][j];
-}
-
-void
-subm(Matrix a, Matrix b)
-{
-	int i, j;
-
-	for(i = 0; i < 3; i++)
-		for(j = 0; j < 3; j++)
-			a[i][j] -= b[i][j];
-}
-
-void
-mulm(Matrix a, Matrix b)
-{
-	int i, j, k;
-	Matrix r;
-
-	for(i = 0; i < 3; i++)
-		for(j = 0; j < 3; j++){
-			r[i][j] = 0;
-			for(k = 0; k < 3; k++)
-				r[i][j] += a[i][k]*b[k][j];
-		}
-	for(i = 0; i < 3; i++)
-		for(j = 0; j < 3; j++)
-			a[i][j] = r[i][j];
-}
-
-void
-transm(Matrix m)
-{
-	int i, j;
-	double tmp;
-
-	for(i = 0; i < 3; i++)
-		for(j = i; j < 3; j++){
-			tmp = m[i][j];
-			m[i][j] = m[j][i];
-			m[j][i] = tmp;
-		}
-}
-
-double
-detm(Matrix m)
-{
-	return m[0][0]*(m[1][1]*m[2][2] - m[1][2]*m[2][1])
-		+ m[0][1]*(m[1][2]*m[2][0] - m[1][0]*m[2][2])
-		+ m[0][2]*(m[1][0]*m[2][1] - m[1][1]*m[2][0]);
-}
-
-Vector
-mulvecm(Vector v, Matrix m)
-{
-	Vector r;
-
-	r.x = v.x * m[0][0] + v.y * m[0][1] + v.w * m[0][2];
-	r.y = v.x * m[1][0] + v.y * m[1][1] + v.w * m[1][2];
-	r.w = v.x * m[2][0] + v.y * m[2][1] + v.w * m[2][2];
-	return r;
-}
--- a/mkfile
+++ b/mkfile
@@ -1,13 +1,12 @@
 </$objtype/mkfile
 
-BIN=/$objtype/bin/
+BIN=/$objtype/bin/games
 TARG=ballistics
 OFILES=\
 	main.$O\
-	util.$O\
-	vector.$O\
-	matrix.$O
 
-HFILES=dat.h fns.h
+HFILES=\
+	dat.h\
+	fns.h
 
 </sys/src/cmd/mkone
--- a/util.c
+++ /dev/null
@@ -1,16 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include "dat.h"
-#include "fns.h"
-
-double
-round(double n)
-{
-	return floor(n + 0.5);
-}
-
-double
-hypot3(double x, double y, double z)
-{
-	return hypot(x, hypot(y, z));
-}
--- a/vector.c
+++ /dev/null
@@ -1,48 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include "dat.h"
-#include "fns.h"
-
-Vector
-Vec(double x, double y, double w)
-{
-	return (Vector){x, y, w};
-}
-
-Vector
-addvec(Vector v, Vector u)
-{
-	return (Vector){v.x+u.x, v.y+u.y, v.w+u.w};
-}
-
-Vector
-subvec(Vector v, Vector u)
-{
-	return (Vector){v.x-u.x, v.y-u.y, v.w-u.w};
-}
-
-Vector
-mulvec(Vector v, double s)
-{
-	return (Vector){v.x*s, v.y*s, v.w*s};
-}
-
-double
-dotvec(Vector v, Vector u)
-{
-	return v.x*u.x + v.y*u.y + v.w*u.w;
-}
-
-Vector
-normvec(Vector v)
-{
-	double len;
-
-	len = hypot3(v.x, v.y, v.w);
-	if(len == 0)
-		return (Vector){0, 0, 0};
-	v.x /= len;
-	v.y /= len;
-	v.w /= len;
-	return v;
-}