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.
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. (not recommended, this is under rewrite)
You can also check out the hexameter.example.swt project here.
Hexameter currently supports a maximum grid size of 1000 * 1000 (1.000.000 cells) with the default implementation but you can provide your own storage implementation to alleviate this limitation.
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 fork adds an array of vertex-indices (as of eeb9b) that doesn't really make any sense without the libGDX game library.
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.hexameter</groupId>
<artifactId>hexameter.core</artifactId>
<version>2017.1.0</version>
</dependency>
You can also use Gradle:
'org.codetome.hexameter:hexameter.core:2017.1.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);
You can fetch the Hexagon
s stored on a grid using the getHexagons
method:
Observable<Hexagon> hexagons = grid.getHexagons();
After that you can iterate over all the Point
s of your Hexagon
s:
hexagons.forEach(new Action1<Hexagon>() {
@Override
public void call(Hexagon hexagon) {
for (Point point : hexagon.getPoints()) {
// do what you want
}
}
});
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.
You can find a simple GUI example in the hexameter.example.swt
project. Run it by doing the following steps.
- Clone the project:
git clone [email protected]:Hexworks/hexameter.example.swt.git
- cd to the newly created
hexameter.example.swt
folder:cd hexameter.example.swt/
- build the project:
./gradlew clean build
(orgradlew clean build
on Windows) - run the created uberjar:
java -jar build/libs/hexameter.example.swt.jar
- Querying the characteristics of the
HexagonGrid
- Fetching all the
Hexagon
objects from the grid - Getting a subset of Hexagons (using cube or offset coordinate range) from the grid
- Checking whether a Hexagon is on a grid or not
- Getting a
Hexagon
by its grid coordinate (cube) - Getting a
Hexagon
by its pixel coordinate - Getting the neighbors of a hexagon (also by index)
- Calculating the distance between two
Hexagon
s - Calculating the movement range from a
Hexagon
to an other - Rotating a
Hexagon
- Calculating a ring from a
Hexagon
- Draw a line from a
Hexagon
to an other - Checking visibility of a
Hexagon
from an other - Adding custom data to a Hexagon
- Clearing all custom data from the HexagonalGrid
Check these interfaces for more details:
- You can add satellite data (any arbitrary data you have) to a
Hexagon
. By implementing theSatelliteData
interface you gain operations like visibility checking - Hexameter comes with a sensible default implementation of
SatelliteData
so if you don't want to add extra data you can useDefaultSatelliteData
. - You can use your own implementation of
HexagonDataStorage
for storing yourHexagon
s - Hexameter comes with a sensible
DefaultHexagonDataStorage
implementation which stores all data in memory - You don't have to fetch all
Hexagon
objects by using thegetHexagons
method. You can queryHexagon
s by a range using offset or cube coordinates
- Path finding with obstacles (blocking movement)
- Movement range with obstacles and movement cost calculation
- Android example
This project exists thanks to all the people who contribute. [Contribute].
Thank you to all our backers! 🙏 [Become a backer]
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]
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!