+++ /dev/null
-package tim.prune.gui.map;
-
-/**
- * Class to hold the current position of the map
- */
-public class MapPosition
-{
- /** Width and height of each tile of map */
- private static final int MAP_TILE_SIZE = 256;
-
- /** x position (scale depends on zoom) */
- private int _xPosition = 0;
- /** y position (scale depends on zoom) */
- private int _yPosition = 0;
-
- /** Zoom level, from 2 to max */
- private int _zoom = 12;
- /** Factor to zoom by, 2 to the power of zoom */
- private int _zoomFactor = 1 << _zoom;
- /** Maximum zoom level */
- private static final int MAX_ZOOM = 21;
-
-
- /**
- * Zoom and pan to show the selected area
- * @param inMinX minimum transformed X
- * @param inMaxX maximum transformed X
- * @param inMinY minimum transformed Y
- * @param inMaxY maximum transformed Y
- * @param inWidth width of display
- * @param inHeight height of display
- */
- public void zoomToXY(double inMinX, double inMaxX, double inMinY, double inMaxY, int inWidth, int inHeight)
- {
- // System.out.println("Zooming to " + inMinX + ", " + inMaxX + ", " + inMinY + ", " + inMaxY + "; width=" + inWidth + ", height=" + inHeight);
- double diffX = Math.abs(inMaxX - inMinX);
- double diffY = Math.abs(inMaxY - inMinY);
- // Find out what zoom level to go to
- int requiredZoom = -1;
- for (int currZoom = MAX_ZOOM; currZoom >= 2; currZoom--)
- {
- if (transformToPixels(diffX, currZoom) < inWidth
- && transformToPixels(diffY, currZoom) < inHeight)
- {
- requiredZoom = currZoom;
- break;
- }
- }
- if (requiredZoom < 2) requiredZoom = 2;
- // Set position
- setZoom(requiredZoom);
- _xPosition = transformToPixels((inMinX + inMaxX) / 2.0);
- _yPosition = transformToPixels((inMinY + inMaxY) / 2.0);
- }
-
- /**
- * Ensure that zoom and zoomFactor remain in sync
- * @param inZoom zoom level to set
- */
- private void setZoom(int inZoom)
- {
- _zoom = inZoom;
- _zoomFactor = 1 << _zoom;
- }
-
- /**
- * Zoom and pan to show the selected area
- * @param inMinX minimum pixels X
- * @param inMaxX maximum pixels X
- * @param inMinY minimum pixels Y
- * @param inMaxY maximum pixels Y
- * @param inWidth width of display
- * @param inHeight height of display
- */
- public void zoomToPixels(int inMinX, int inMaxX, int inMinY, int inMaxY, int inWidth, int inHeight)
- {
- // System.out.println("Current position is " + _xPosition + ", " + _yPosition);
- int diffX = Math.abs(inMaxX - inMinX);
- int diffY = Math.abs(inMaxY - inMinY);
- // Find out what zoom level to go to
- int requiredZoom = -1;
- int multFactor = 0;
- for (int currZoom = MAX_ZOOM; currZoom >= _zoom; currZoom--)
- {
- multFactor = 1 << (currZoom - _zoom);
- if ((diffX * multFactor) < inWidth && (diffY * multFactor) < inHeight)
- {
- requiredZoom = currZoom;
- break;
- }
- }
- setZoom(requiredZoom);
- // Set position
- _xPosition = (_xPosition - inWidth/2 + (inMinX + inMaxX) / 2) * multFactor;
- _yPosition = (_yPosition - inHeight/2 + (inMinY + inMaxY) / 2) * multFactor;
- }
-
- /**
- * Transform a given coordinate into pixels using the current zoom value
- * @param inValue value to transform
- * @return pixels
- */
- private int transformToPixels(double inValue)
- {
- return transformToPixels(inValue, _zoom);
- }
-
- /**
- * Transform a given coordinate into pixels using the specified zoom value
- * @param inValue value to transform
- * @param inZoom zoom value to use
- * @return pixels
- */
- private static int transformToPixels(double inValue, int inZoom)
- {
- return (int) (inValue * MAP_TILE_SIZE * (1 << inZoom));
- }
-
- /**
- * Convert pixels back into x coordinates
- * @param inPixelX x coordinate on screen
- * @param inWidth current width of window
- * @return x coordinate
- */
- public double getXFromPixels(int inPixelX, int inWidth)
- {
- return ((inPixelX - inWidth/2) + _xPosition) * 1.0 / MAP_TILE_SIZE / _zoomFactor;
- }
-
- /**
- * Convert pixels back into y coordinates
- * @param inPixelY y coordinate on screen
- * @param inHeight current height of window
- * @return y coordinate
- */
- public double getYFromPixels(int inPixelY, int inHeight)
- {
- return ((inPixelY - inHeight/2) + _yPosition) * 1.0 / MAP_TILE_SIZE / _zoomFactor;
- }
-
- /**
- * Get the horizontal offset from the centre
- * @param inValue value to transform
- * @return number of pixels right (+ve) or left (-ve) from the centre
- */
- public int getXFromCentre(double inValue)
- {
- return transformToPixels(inValue) - _xPosition;
- }
-
- /**
- * Get the vertical offset from the centre
- * @param inValue value to transform
- * @return number of pixels up (+ve) or down (-ve) from the centre
- */
- public int getYFromCentre(double inValue)
- {
- return transformToPixels(inValue) - _yPosition;
- }
-
- /**
- * Convert a pixel value into a bounds value for sensitivity
- * @param inPixels number of pixels
- * @return bounds value to use for x,y checking
- */
- public double getBoundsFromPixels(int inPixels) {
- return (inPixels * 1.0 / MAP_TILE_SIZE / _zoomFactor);
- }
-
- /**
- * Get the leftmost, rightmost, upper and lower index boundaries for the tiles to display
- * @param inWidth width of window
- * @param inHeight height of window
- * @return tile indices as array left, right, up, down
- */
- public int[] getTileIndices(int inWidth, int inHeight)
- {
- int[] result = new int[4];
- result[0] = getTileIndex(_xPosition - inWidth/2);
- result[1] = getTileIndex(_xPosition + inWidth/2);
- result[2] = getTileIndex(_yPosition - inHeight/2);
- result[3] = getTileIndex(_yPosition + inHeight/2);
- return result;
- }
-
- /**
- * Get the pixel offsets for the display
- * @param inWidth width of window
- * @param inHeight height of window
- * @return offsets as x, y
- */
- public int[] getDisplayOffsets(int inWidth, int inHeight)
- {
- int[] result = new int[2];
- result[0] = getDisplayOffset(_xPosition - inWidth/2);
- result[1] = getDisplayOffset(_yPosition - inHeight/2);
- return result;
- }
-
- /**
- * @return x index of the centre tile
- */
- public int getCentreTileX()
- {
- return getTileIndex(_xPosition);
- }
-
- /**
- * @return y index of the centre tile
- */
- public int getCentreTileY()
- {
- return getTileIndex(_yPosition);
- }
-
- /**
- * @param inPosition position of point
- * @return tile index for that point
- */
- private int getTileIndex(int inPosition)
- {
- return inPosition / MAP_TILE_SIZE;
- }
-
- /**
- * @param inPosition position of point
- * @return pixel offset for that point
- */
- private int getDisplayOffset(int inPosition)
- {
- return inPosition % MAP_TILE_SIZE;
- // I thought that &255 would be slightly faster, but it gives the wrong result
- }
-
- /**
- * Zoom in one level
- */
- public void zoomIn()
- {
- if (_zoom < MAX_ZOOM)
- {
- setZoom(_zoom + 1);
- _xPosition *= 2;
- _yPosition *= 2;
- }
- }
-
- /**
- * Zoom out one level
- */
- public void zoomOut()
- {
- if (_zoom >= 3)
- {
- setZoom(_zoom - 1);
- _xPosition /= 2;
- _yPosition /= 2;
- }
- }
-
- /**
- * @return current zoom level
- */
- public int getZoom()
- {
- return _zoom;
- }
-
- /**
- * Pan map by the specified amount
- * @param inDeltaX amount to pan right
- * @param inDeltaY amount to pan down
- */
- public void pan(int inDeltaX, int inDeltaY)
- {
- // TODO: Check bounds?
- _xPosition += inDeltaX;
- _yPosition += inDeltaY;
- }
-}