Basically, the issue I am trying to solve is that of "zooming round a point in a graphic, so that this point stays put on the display".
First, here is how I display the curve within a rectangle on screen :
The curve has xmin, xmax, ymin and ymax coordinates and so does the rectangle. Displaying the curve is just a matter of computing an affine transformation (xa, xb, ya, yb) that will map any point of the curve within xmin .. xmax ; ymin .. ymax boundaries to that of the rectangle. Let P(x,y) be a point of the curve. The corresponding pixel to light has screen coordinates (x * xa + xb , y * ya + yb).
Now, I have tried to solve the zoom problem using different approaches. The latest one (the one that gives the best results) is obtained by considering that :
– Zooming is achieved by actually narrowing xmin ... xmax and ymin .. ymax coordinates of the curve, since the size of the display rectangle stays constant.
Thus, if I want to perform a x2 zoom of a factor f, I can proceed in two steps :
- Keep the origin (xmin, ymin) and scale the width giving the new boundaries to display :
new_xmin = xmin
new_xmax = ((xmax - xmin) / f) + xmin
new_ymin = ymin
new_ymax = ((ymax - ymin) / f) + ymin
That achieves the zoom, keeping the origin stable. That's not what I want. I want to keep a point P(px, py) belonging to the initial range at the same place in the display rectangle. So I need to translate these coordinates by kx, ky to keep a point P(x,y) that was inside the first boundaries at the same place of the screen. Here is what I came up with :
kx = (px - xmin) * f - (px - xmin) / (xmax - xmin)
ky = (py - ymin) * f - (py - ymin) / (ymax - ymin)
So, the new coordinates to display are :
new_xmin = xmin - kx
new_xmax = ((xmax - xmin) / f) + xmin - kx
new_ymin = ymin - ky
new_ymax = ((ymax - ymin) / f) + ymin -ky
That's close, but it doesn't work. kx and ky are too small and zooming mostly look like it's happening around xmin,ymin.
Any suggestions ? Thanks for enlightinig me...
EDIT: In this approach I do not take into account the width or height of the display rectangle. Is it a mistake? I do not feel like it is of importance since it does not change.
The problem can be dealt with for the $x$- and $y$-direction separately. In both directions you are given two nested compact intervals $$[u,v]\subset[a,b]\subset{\mathbb R}$$ with $v-u>0$, and want a bijective affine map $f:\>[u,v]\to[a,b]$. There is a unique such map $$f(x):={v-x\over v-u} a+{x-u\over v-u} b\ .$$ This map has a zoom factor $\sigma:={\displaystyle{b-a\over v-u}}\geq1$. If $\sigma>1$ there is a unique fixed point $$\xi:={(b-v)u+(u-a)v\over(b-v)+(u-a)}\ \in[u,v]\ .$$ If you want to realize the zoom live (i.e., in real time $t$) with center point $\xi$ you can write $$F(x,t)=\xi+\sigma(x-\xi)\qquad(1\leq t\leq \sigma)\ .$$ Then $F(x,1)=x$, and $F(x,\sigma)=f(x)$.
Note that the resulting zoom factors for the $x$- and the $y$-direction are different. If this is not desired additional measures have to be taken.