magomar
9/4/2013 - 9:49 AM

## JPanel implementation of an hexagonal map, with methods to convert between pixels and map coordinates (both directions, from map coordinates

JPanel implementation of an hexagonal map, with methods to convert between pixels and map coordinates (both directions, from map coordinates to pixels and viceversa)

``````import javax.swing.*;
import java.awt.*;

public class HexagonalMap extends JPanel {
private int width; // Number of columns
private int height; // Number of rows
private int hexSide; // Side of the hexagon
private int hexOffset; // Distance from left horizontal vertex to vertical axis
private int hexApotheme; // Apotheme of the hexagon = radius of inscribed circumference
private int hexRectWidth; // Width of the circumscribed rectangle
private int hexRectHeight; // Height of the circumscribed rectangle
private int hexGridWidth;  // hexOffset + hexSide (b + s)

public HexagonalMap(int width, int height, int hexSide) {
this.width = width;
this.height = height;
this.hexSide = hexSide;
hexApotheme = (int) (hexSide * Math.cos(Math.PI / 6));
hexOffset = (int) (hexSide * Math.sin(Math.PI / 6));
hexGridWidth = hexOffset + hexSide;
hexRectWidth = 2 * hexOffset + hexSide;
hexRectHeight = 2 * hexApotheme;
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
g.drawPolygon(buildHexagon(i, j));
}
}
}

@Override
public Dimension getPreferredSize() {
int panelWidth = width * hexGridWidth + hexOffset;
int panelHeight = height * hexRectHeight + hexApotheme + 1;
return new Dimension(panelWidth, panelHeight);
}

Polygon buildHexagon(int column, int row) {
Polygon hex = new Polygon();
Point origin = tileToPixel(column, row);
hex.addPoint(origin.x + hexRectWidth, origin.y + hexApotheme);
hex.addPoint(origin.x + hexGridWidth, origin.y + hexRectHeight);
hex.addPoint(origin.x + hexOffset, origin.y + hexRectHeight);
return hex;
}

Point tileToPixel(int column, int row) {
Point pixel = new Point();
pixel.x = hexGridWidth * column;
if (Util.isOdd(column)) pixel.y = hexRectHeight * row;
else pixel.y = hexRectHeight * row + hexApotheme;
return pixel;
}

Point pixelToTile(int x, int y) {
double hexRise = (double) hexApotheme / (double) hexOffset;
Point p = new Point(x / hexGridWidth, y / hexRectHeight);
Point r = new Point(x % hexGridWidth, y % hexRectHeight);
Direction direction;
if (Util.isOdd(p.x)) { //odd column
if (r.y < -hexRise * r.x + hexApotheme) {
direction = Direction.NW;
} else if (r.y > hexRise * r.x + hexApotheme) {
direction = Direction.SW;
} else {
direction = Direction.C;
}
} else { //even column
if (r.y > hexRise * r.x && r.y < -hexRise * r.x + hexRectHeight) {
direction = Direction.NW;
} else if (r.y < hexApotheme) {
direction = Direction.N;
} else direction = Direction.C;
}
return new Point(direction.getNeighborCoordinates(p));
}

public boolean tileIsWithinBoard(Point coordinates) {
int column = coordinates.x;
int row = coordinates.y;
return (column >= 0 && column < width) && (row >= 0 && row < height);
}
}
``````