games/galaxy: fix zoom

Zooming when far away from the center of gravity
of the galaxy would zoom the center of the screen
out of view. Now adjust the origin so that the
center of the screen stays centered
This commit is contained in:
spew 2017-03-12 18:24:45 -05:00
parent ffa430c570
commit dff1e3813f
3 changed files with 52 additions and 32 deletions

View file

@ -31,14 +31,23 @@ body(void)
return b; return b;
} }
Point
topoint(Vector v)
{
Point p;
p.x = v.x/scale + orig.x;
p.y = v.y/scale + orig.y;
return p;
}
void void
drawbody(Body *b) drawbody(Body *b)
{ {
Point pos, v; Point pos, v;
int s; int s;
pos.x = b->x / scale + orig.x; pos = topoint(b->Vector);
pos.y = b->y / scale + orig.y;
s = b->size/scale; s = b->size/scale;
fillellipse(screen, pos, s, s, b->col, ZP); fillellipse(screen, pos, s, s, b->col, ZP);
v.x = b->v.x/scale*10; v.x = b->v.x/scale*10;

View file

@ -171,8 +171,7 @@ drawglxy(void)
draw(screen, screen->r, display->black, 0, ZP); draw(screen, screen->r, display->black, 0, ZP);
for(b = glxy.a; b < glxy.a + glxy.l; b++) { for(b = glxy.a; b < glxy.a + glxy.l; b++) {
pos.x = b->x / scale + orig.x; pos = topoint(b->Vector);
pos.y = b->y / scale + orig.y;
s = b->size/scale; s = b->size/scale;
fillellipse(screen, pos, s, s, b->col, ZP); fillellipse(screen, pos, s, s, b->col, ZP);
if(showv) { if(showv) {
@ -198,8 +197,7 @@ setsize(Body *b)
Point pos, d; Point pos, d;
double h; double h;
pos.x = b->x / scale + orig.x; pos = topoint(b->Vector);
pos.y = b->y / scale + orig.y;
d = subpt(mc->xy, pos); d = subpt(mc->xy, pos);
h = hypot(d.x, d.y); h = hypot(d.x, d.y);
b->size = h == 0 ? scale : h*scale; b->size = h == 0 ? scale : h*scale;
@ -211,18 +209,10 @@ setvel(Body *b)
{ {
Point pos, d; Point pos, d;
pos.x = b->x / scale + orig.x; pos = topoint(b->Vector);
pos.y = b->y / scale + orig.y;
d = subpt(mc->xy, pos); d = subpt(mc->xy, pos);
b->v.x = (double)d.x*scale/10; b->v.x = d.x*scale/10;
b->v.y = (double)d.y*scale/10; b->v.y = d.y*scale/10;
}
void
setpos(Body *b)
{
b->x = (mc->xy.x - orig.x) * scale;
b->y = (mc->xy.y - orig.y) * scale;
} }
void void
@ -275,7 +265,6 @@ dobody(void)
} }
b = body(); b = body();
setpos(b);
setvel(b); setvel(b);
setsize(b); setsize(b);
b->col = randcol(); b->col = randcol();
@ -290,7 +279,7 @@ dobody(void)
else if(mc->buttons == 5) else if(mc->buttons == 5)
dovel(b); dovel(b);
else else
setpos(b); b->Vector = tovector(mc->xy);
} }
CHECKLIM(b, f); CHECKLIM(b, f);
@ -349,30 +338,41 @@ domove(void)
setcursor(mc, cursor); setcursor(mc, cursor);
} }
Point
screencenter(void)
{
Point sc;
sc = divpt(subpt(screen->r.max, screen->r.min), 2);
return addpt(screen->r.min, sc);
}
void void
dozoom(void) dozoom(void)
{ {
Point z, d; Point oxy, d, sc, off;
double f, olds; Vector gsc;
double z, oscale;
setcursor(mc, &zoomcursor); setcursor(mc, &zoomcursor);
oxy = mc->xy;
z = mc->xy; oscale = scale;
olds = scale;
for(;;) { for(;;) {
readmouse(mc); readmouse(mc);
if(mc->buttons != 2) if(mc->buttons != 2)
break; break;
d = subpt(mc->xy, z); d = subpt(mc->xy, oxy);
f = tanh((double)d.y/200) + 1; z = tanh((double)d.y/200) + 1;
sc = screencenter();
gsc = tovector(sc);
pause(0, 0); pause(0, 0);
scale = f*olds; scale = z*oscale;
off = subpt(topoint(gsc), sc);
orig = subpt(orig, off);
drawglxy(); drawglxy();
pause(1, 0); pause(1, 0);
} }
setcursor(mc, cursor); setcursor(mc, cursor);
pause(1, 0);
} }
void void
@ -579,6 +579,16 @@ Again:
} }
} }
Vector
tovector(Point p)
{
Vector v;
v.x = (p.x-orig.x) * scale;
v.y = (p.y-orig.y) * scale;
return v;
}
void void
usage(void) usage(void)
{ {
@ -632,8 +642,7 @@ threadmain(int argc, char **argv)
sysfatal("initmouse failed: %r"); sysfatal("initmouse failed: %r");
dt² = dt*dt; dt² = dt*dt;
orig = divpt(subpt(screen->r.max, screen->r.min), 2); orig = screencenter();
orig = addpt(orig, screen->r.min);
glxyinit(); glxyinit();
quadsinit(); quadsinit();
if(doload) if(doload)

View file

@ -55,14 +55,16 @@ Body ZB;
QB space; QB space;
Image *randcol(void); Image *randcol(void);
Point topoint(Vector);
Vector tovector(Point);
Body *body(void); Body *body(void);
void drawbody(Body*); void drawbody(Body*);
Vector center(void); Vector center(void);
void glxyinit(void); void glxyinit(void);
int Bfmt(Fmt*);
void readglxy(int); void readglxy(int);
void writeglxy(int); void writeglxy(int);
int Bfmt(Fmt*);
void quadcalc(Body*, QB, double); void quadcalc(Body*, QB, double);
int quadins(Body*, double); int quadins(Body*, double);