Hexameter is a hexagonal grid library. The motivation behind it is to have an optimized, simple and usable library for drawing hexagonal grids without being tied to any GUI framework. It is 100% unit tested (apart from some generated code).
This means that you can use Hexameter on Android, your backend or your desktop app. There is a REST-based web example which you can tinker with here. You can also check out more code examples in the hexameter-examples project here.
Hexameter currently supports a maximum grid size of 1000 * 1000 (1.000.000 cells). This is a known limitation and it will be worked around in a later release.
Now Hexameter has been backported to support Android!
Note that this library uses RxJava. You should familiarize yourself with the basics (nothing more needed) in order to use it effectively. If you don't want to learn RxJava don't worry the code examples below can be used without diving into the details.
This library uses Amit's guide to hexagonal grids. The coordinate system used by this library is the Cubic coordinate system. Please check here for further details.
Hexagonal grids come in flat topped and pointy topped shapes. The grid can have several layouts:
- Hexagonal: the width and height of a this layout has to be equal and both have to be an odd number.
- Triangular: the width and height of a this layout has to be equal.
- Rectangular: no special rules
- Trapezoid: no special rules
All layouts have with and height values of at least 1. You can consult HexagonalGridLayout if you need further details.
This library is not tied to any GUI implementation. All operations provided by the API are working using the most abstract concept possible.
Let's start by adding Hexameter as a Maven dependency to your project:
<dependency>
<groupId>org.codetome</groupId>
<artifactId>hexameter</artifactId>
<version>2.0.0</version>
</dependency>
You can also use Gradle:
'org.codetome:hexameter:2.0.0'
You can use the HexagonalGridBuilder from the API package to create a HexagonalGrid:
import org.codetome.hexameter.core.api.HexagonalGridLayout;
import org.codetome.hexameter.core.api.HexagonOrientation;
import org.codetome.hexameter.core.api.HexagonalGrid;
import org.codetome.hexameter.core.api.HexagonalGridBuilder;
import static org.codetome.hexameter.core.api.HexagonalGridLayout.RECTANGULAR;
import static org.codetome.hexameter.core.api.HexagonOrientation.FLAT_TOP;
// ...
private static final int GRID_HEIGHT = 9;
private static final int GRID_WIDTH = 9;
private static final HexagonalGridLayout GRID_LAYOUT = RECTANGULAR;
private static final HexagonOrientation ORIENTATION = FLAT_TOP;
private static final double RADIUS = 30;
// ...
HexagonalGriBuilder builder = new HexagonalGridBuilder()
.setGridHeight(GRID_HEIGHT)
.setGridWidth(GRID_WIDTH)
.setGridLayout(GRID_LAYOUT)
.setOrientation(ORIENTATION)
.setRadius(RADIUS);
HexagonalGrid grid = builder.build();
You can also use the HexagonalGridBuilder to create a HexagonalGridCalculator for you which supports advanced operations on HexagonalGrids:
import org.codetome.hexameter.core.api.HexagonalGridCalculator;
// ...
HexagonalGridCalculator calculator = builder.buildCalculatorFor(grid);
First you want to fetch all the Hexagon
s from your grid:
Collection<Hexagon> hexagons = grid.getHexagons();
After that you can iterate over all the Point
s of your Hexagon
s:
hexagonalGrid.getHexagons().forEach(new Action1<Hexagon>() {
@Override
public void call(Hexagon hexagon) {
for(Point point : hexagon.getPoints()) {
// your draw logic here
}
}
});
Note that each Point
represents a coordinate in 2D space. You can use them for drawing.
There are basically only one operation for manipulating your data on the grid:
The Hexagon#setSatelliteData(T data)
operation with which you can add your own arbitrary
data to a Hexagon
object. This means that once created a HexagonalGrid
is immutable apart from the
satellite data you add.
There is also a HexagonalGrid#clearSatelliteData()
method for clearing all satellite data from your grid.
The implementation of the HexagonalGrid
is lazy. This means that it only stores data which is absolutely necessary
to keep in memory (the coordinates and your satellite data). Everything else is generated on the fly. The only limiting
factor of a grid at the moment is the coordinates (which consume memory) and the satellite data. This will be worked
around later.
You can find a simple GUI example in the hexameter-swt-example
submodule. Run it by doing the following steps.
- Clone the project:
git clone git@github.com:adam-arold/hexameter.git
- cd to the newly created
hexameter
folder:cd hexameter/
- build the project:
mvn clean install
- run the created uberjar:
java -jar ./hexameter-swt-example/target/hexameter-swt-example-1.0.0.jar
- Getting a hexagon by its grid coordinate
- Getting a hexagon by its pixel coordinate
- Getting the neighbors of a hexagon
- Calculating the distance between two hexagons
- Calculating the movement range from a hexagon
- Checking whether a Hexagon is on a grid or not
- Adding custom data to a Hexagon
- Clearing all custom data from the HexagonalGrid
- Getting a subset of Hexagons (using cube or offset coordinate range) from the grid
Check these interfaces for more details:
- Field of view calculation with obstacles (blocking vision)
- Path finding with obstacles (blocking movement)
- Movement range with obstacles and movement cost calculation
- Rotation calculation
- Option for arbitrary storage objects thus alleviating the 1000*1000 limit
- Android example
Hexameter is made available under the MIT License.
Hexameter is created and maintained by Adam Arold
I'm open to suggestions, feel free to comment or to send me a message. Pull requests are also welcome!