ref: d6be49085c76bbea87b7d7c61455b93883669bf1
parent: 168a16b70a928ed64061bdac7fc9d52235c3f9fc
author: rodri <[email protected]>
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;
-}