Ich habe bereits eine ähnliche Frage mit identischen Zielen beantwortet. Zum besseren Verständnis werde ich sie hier erneut veröffentlichen: (Hinweis: Der gesamte Code ist in Java geschrieben und getestet.)
Dieses Bild zeigt die linke obere Ecke eines hexagonalen Gitters und darüber ein blaues quadratisches Gitter. Es ist leicht zu finden, in welchem der Quadrate sich ein Punkt befindet, und dies würde auch eine grobe Annäherung an welches Sechseck ergeben. Die weißen Teile der Sechsecke zeigen, wo das quadratische und das sechseckige Gitter die gleichen Koordinaten haben, und die grauen Teile der Sechsecke zeigen, wo sie keine Koordinaten haben.
Die Lösung ist jetzt so einfach, dass Sie herausfinden, in welchem Feld sich ein Punkt befindet, prüfen, ob sich der Punkt in einem der Dreiecke befindet, und gegebenenfalls die Antwort korrigieren.
private final Hexagon getSelectedHexagon(int x, int y)
{
// Find the row and column of the box that the point falls in.
int row = (int) (y / gridHeight);
int column;
boolean rowIsOdd = row % 2 == 1;
// Is the row an odd number?
if (rowIsOdd)// Yes: Offset x to match the indent of the row
column = (int) ((x - halfWidth) / gridWidth);
else// No: Calculate normally
column = (int) (x / gridWidth);
An diesem Punkt haben wir die Zeile und Spalte des Feldes, in dem sich unser Punkt befindet. Als nächstes müssen wir unseren Punkt an den beiden oberen Kanten des Sechsecks testen, um festzustellen, ob unser Punkt in einem der obigen Sechsecke liegt:
// Work out the position of the point relative to the box it is in
double relY = y - (row * gridHeight);
double relX;
if (rowIsOdd)
relX = (x - (column * gridWidth)) - halfWidth;
else
relX = x - (column * gridWidth);
Relative Koordinaten zu haben, erleichtert den nächsten Schritt.
Wenn das y unseres Punktes wie im obigen Bild > mx + c ist , wissen wir, dass unser Punkt über der Linie liegt, und in unserem Fall das Sechseck über und links von der aktuellen Zeile und Spalte. Beachten Sie, dass das Koordinatensystem in Java in der oberen linken Ecke des Bildschirms mit y beginnt und nicht wie in der Mathematik üblich unten links, daher der negative Farbverlauf für den linken Rand und der positive Farbverlauf für den rechten Rand.
// Work out if the point is above either of the hexagon's top edges
if (relY < (-m * relX) + c) // LEFT edge
{
row--;
if (!rowIsOdd)
column--;
}
else if (relY < (m * relX) - c) // RIGHT edge
{
row--;
if (rowIsOdd)
column++;
}
return hexagons[column][row];
}
Eine kurze Erklärung der im obigen Beispiel verwendeten Variablen:
m ist der Gradient, also m = c / halbe Breite
NeoShamams Ergänzung zu den oben genannten
Dies ist ein Nachtrag zu SebastianTroys Antwort. Ich würde es als Kommentar hinterlassen, aber ich habe noch nicht genug Ruf.
Wenn Sie ein axiales Koordinatensystem wie hier beschrieben implementieren möchten:
http://www.redblobgames.com/grids/hexagons/
Sie können den Code leicht ändern.
Anstatt von
// Is the row an odd number?
if (rowIsOdd)// Yes: Offset x to match the indent of the row
column = (int) ((x - halfWidth) / gridWidth);
else// No: Calculate normally
column = (int) (x / gridWidth);
benutze das
float columnOffset = row * halfWidth;
column = (int)(x + columnOffset)/gridWidth; //switch + to - to align the grid the other way
Dadurch befindet sich die Koordinate (0, 2) in der gleichen diagonalen Spalte wie (0, 0) und (0, 1), anstatt direkt unter (0, 0) zu liegen.