ref: fe914952f84dbc5c6d860c49ff4ae211266f0ad9
parent: 5d5944cb47b0108f32387dc09e28366a9d66859d
author: spew <devnull@localhost>
date: Sun Mar 12 14:24:45 EDT 2017
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
--- a/sys/src/games/galaxy/body.c
+++ b/sys/src/games/galaxy/body.c
@@ -31,6 +31,16 @@
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
drawbody(Body *b)
{@@ -37,8 +47,7 @@
Point pos, v;
int s;
- pos.x = b->x / scale + orig.x;
- pos.y = b->y / scale + orig.y;
+ pos = topoint(b->Vector);
s = b->size/scale;
fillellipse(screen, pos, s, s, b->col, ZP);
v.x = b->v.x/scale*10;
--- a/sys/src/games/galaxy/galaxy.c
+++ b/sys/src/games/galaxy/galaxy.c
@@ -171,8 +171,7 @@
draw(screen, screen->r, display->black, 0, ZP);
for(b = glxy.a; b < glxy.a + glxy.l; b++) {- pos.x = b->x / scale + orig.x;
- pos.y = b->y / scale + orig.y;
+ pos = topoint(b->Vector);
s = b->size/scale;
fillellipse(screen, pos, s, s, b->col, ZP);
if(showv) {@@ -198,8 +197,7 @@
Point pos, d;
double h;
- pos.x = b->x / scale + orig.x;
- pos.y = b->y / scale + orig.y;
+ pos = topoint(b->Vector);
d = subpt(mc->xy, pos);
h = hypot(d.x, d.y);
b->size = h == 0 ? scale : h*scale;
@@ -211,21 +209,13 @@
{Point pos, d;
- pos.x = b->x / scale + orig.x;
- pos.y = b->y / scale + orig.y;
+ pos = topoint(b->Vector);
d = subpt(mc->xy, pos);
- b->v.x = (double)d.x*scale/10;
- b->v.y = (double)d.y*scale/10;
+ b->v.x = d.x*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
dosize(Body *b)
{Point p;
@@ -275,7 +265,6 @@
}
b = body();
- setpos(b);
setvel(b);
setsize(b);
b->col = randcol();
@@ -290,7 +279,7 @@
else if(mc->buttons == 5)
dovel(b);
else
- setpos(b);
+ b->Vector = tovector(mc->xy);
}
CHECKLIM(b, f);
@@ -349,30 +338,41 @@
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
dozoom(void)
{- Point z, d;
- double f, olds;
+ Point oxy, d, sc, off;
+ Vector gsc;
+ double z, oscale;
setcursor(mc, &zoomcursor);
-
- z = mc->xy;
- olds = scale;
+ oxy = mc->xy;
+ oscale = scale;
for(;;) {readmouse(mc);
if(mc->buttons != 2)
break;
- d = subpt(mc->xy, z);
- f = tanh((double)d.y/200) + 1;
+ d = subpt(mc->xy, oxy);
+ z = tanh((double)d.y/200) + 1;
+ sc = screencenter();
+ gsc = tovector(sc);
pause(0, 0);
- scale = f*olds;
+ scale = z*oscale;
+ off = subpt(topoint(gsc), sc);
+ orig = subpt(orig, off);
drawglxy();
pause(1, 0);
}
-
setcursor(mc, cursor);
- pause(1, 0);
}
void
@@ -579,6 +579,16 @@
}
}
+Vector
+tovector(Point p)
+{+ Vector v;
+
+ v.x = (p.x-orig.x) * scale;
+ v.y = (p.y-orig.y) * scale;
+ return v;
+}
+
void
usage(void)
{@@ -632,8 +642,7 @@
sysfatal("initmouse failed: %r");dt² = dt*dt;
- orig = divpt(subpt(screen->r.max, screen->r.min), 2);
- orig = addpt(orig, screen->r.min);
+ orig = screencenter();
glxyinit();
quadsinit();
if(doload)
--- a/sys/src/games/galaxy/galaxy.h
+++ b/sys/src/games/galaxy/galaxy.h
@@ -55,14 +55,16 @@
QB space;
Image *randcol(void);
+Point topoint(Vector);
+Vector tovector(Point);
Body *body(void);
void drawbody(Body*);
Vector center(void);
void glxyinit(void);
+int Bfmt(Fmt*);
void readglxy(int);
void writeglxy(int);
-int Bfmt(Fmt*);
void quadcalc(Body*, QB, double);
int quadins(Body*, double);
--
⑨