Let’s say we draw a map into the window by using the transformation mentioned in Map to/from Window Coordinate Transformation. Now we want to zoom in/zoom out in the map. When we use the window center for zoom, it is easy to calculate the Upper-Left and Lower-Right map coordinates of the new window. Assume that we zoom in or zoom out by 2. In this situation calculation of the new Upper-Left and Lower-Right map coordinates in Zoom In function could be calculated as in the Figure-1, and in Zoom Out function as in Figure-2. Then we redraw our map by entering our new corner coordinates as used in Map to/from Window Coordinate Transformation.

Figure-1. Zoom In by 2
Figure-2. Zoom Out by 2

But what will happen if we use mouse wheel and don’t want to change the map coordinates of the mouse cursor? I mean zooming without changing the cursor map coordinates.

We will use the same coordinate systems which are mentioned in Map to/from Window Coordinate Transformation, to find the required functionality. When we look at Figure-3 carefully, we could notice that the window coordinates of the mouse cursor (Cp, Rp) will not change when we zoom in/out. This means that map coordinates of the mouse cursor (Xp, Yp) will not change either. Only map coordinates of the window corners can be changed when we zoom.

Figure-3. Zoom to/from Mouse Cursor

We have four unknowns: ULx, ULy, LRx and LRy. So, we need to find four equations to find the values of the unknowns. We assume we zoom in or zoom out by k.

If we leave X0 and Y0 alone in the first two equations and apply 3rd and 4th equations:

Then we can calculate Sx and Sy:

Finally, we can calculate LRx and LRy:

[*] public PointCoor[] CalculateZoomedWindow(PointCoor PreviousUpperLeft, PointCoor CursorWinLocation, int WinWidth, int WinHeight, double ZoomRatio, bool ZoomOut)
{
    double m = ZoomRatio;

    if (ZoomOut)
        m = 1/ZoomRatio;

    PointCoor CursorMapLocation = WindowToMap(CursorWinLocation);
    double ULX = CursorMapLocation.X - (CursorMapLocation.X - PreviousUpperLeft.X) / m;
    double ULY = (PreviousUpperLeft.Y - CursorMapLocation.Y) / m + CursorMapLocation.Y;
    double sx = (CursorMapLocation.X - ULX) / CursorWinLocation.X;
    double sy = (ULY - CursorMapLocation.Y) / CursorWinLocation.Y;
    double LRX = ULX + WinWidth * sx;
    double LRY = ULY - WinHeight * sy;

    PointCoor[] res = new PointCoor[2];
    res[0] = new PointCoor(ULX, ULY);
    res[1] = new PointCoor(LRX, LRY);

    return res;
}
[*] THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir