Skip to content

Commit

Permalink
fix HexagonalCells::computeCoordinates
Browse files Browse the repository at this point in the history
  • Loading branch information
jube committed Aug 11, 2023
1 parent 441a356 commit fc0c958
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 44 deletions.
9 changes: 9 additions & 0 deletions examples/29_grid.cc
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,15 @@ int main() {
grids[current].grid.hover(renderer.mapPixelToCoords(event.mouseCursor.coords));
break;

case gf::EventType::MouseButtonPressed:
{
auto coords = renderer.mapPixelToCoords(event.mouseButton.coords);
auto localCoords = gf::transform(grids[current].grid.getInverseTransform(), coords);
auto position = grids[current].grid.getCells().computeCoordinates(localCoords);
std::cout << "Position: " << position.x << ',' << position.y << '\n';
break;
}

default:
break;
}
Expand Down
7 changes: 7 additions & 0 deletions include/gf/Grid.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@ inline namespace v1 {
*/
static Grid createHexagonal(Vector2i gridSize, float radius, CellAxis axis, CellIndex index);

/**
* @brief Get the underlying cells
*/
const Cells& getCells() const {
return *m_properties;
}

/**
* @brief Set the grid size
*
Expand Down
122 changes: 93 additions & 29 deletions library/core/Cells_Hexagonal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include <cassert>

#include <gf/Log.h>
#include <gf/Span.h>
#include <gf/VectorOps.h>

Expand Down Expand Up @@ -116,50 +117,113 @@ inline namespace v1 {
}

Vector2i HexagonalCells::computeCoordinates(Vector2f position) const noexcept {
// good approximation but would need some tweaking

Vector2i coords = gf::vec(0, 0);
float offset = computeOffset(m_tileSize, m_sideLength, m_axis);
Vector2i coords = {};

switch (m_axis) {
case CellAxis::X:
coords.x = static_cast<int>(position.x / (m_tileSize.width - offset));
switch (m_index) {
case CellIndex::Odd:
if (coords.x % 2 == 0) {
coords.y = static_cast<int>(position.y / m_tileSize.height);
case CellAxis::X: {
const float lx = m_tileSize.width - offset;

const float qx = std::floor(position.x / lx);
const float rx = position.x - qx * lx;
const float nrx = rx / offset;

const float halfy = m_tileSize.height / 2.0f;
const float qy = std::floor(position.y / halfy);
const float ry = position.y - qy * halfy;
const float nry = ry / halfy;

const int x = static_cast<int>(qx);
const int y = static_cast<int>(qy);

coords = vec(x, y);

if ((m_index == CellIndex::Even) == (parity(x) == 0)) {
--coords.y;
}

coords.y = static_cast<int>(std::floor(coords.y / 2.0f));

if (rx < offset) {
if ((m_index == CellIndex::Even) == (parity(x) == 0)) {
if (parity(y) == 0) {
if (nrx < nry) {
--coords.x;
++coords.y;
}
} else {
coords.y = static_cast<int>((position.y - m_tileSize.height / 2) / m_tileSize.height);
if (nrx + nry < 1) {
--coords.x;
}
}
break;
case CellIndex::Even:
if (coords.x % 2 != 0) {
coords.y = static_cast<int>(position.y / m_tileSize.height);
} else {
if (parity(y) == 0) {
if (nrx + nry < 1) {
--coords.x;
--coords.y;
}
} else {
coords.y = static_cast<int>((position.y - m_tileSize.height / 2) / m_tileSize.height);
if (nrx < nry) {
--coords.x;
}
}
break;
}
}

break;
case CellAxis::Y:
coords.y = static_cast<int>(position.y / (m_tileSize.height - offset));
switch (m_index) {
case CellIndex::Odd:
if (coords.y % 2 == 0) {
coords.x = static_cast<int>(position.x / m_tileSize.width);
}

case CellAxis::Y: {
const float ly = m_tileSize.height - offset;

const float qy = std::floor(position.y / ly);
const float ry = position.y - qy * ly;
const float nry = ry / offset;

const float halfx = m_tileSize.width / 2.0f;
const float qx = std::floor(position.x / halfx);
const float rx = position.x - qx * halfx;
const float nrx = rx / halfx;

const int x = static_cast<int>(qx);
const int y = static_cast<int>(qy);

coords = vec(x, y);

if ((m_index == CellIndex::Even) == (parity(y) == 0)) {
--coords.x;
}

coords.x = static_cast<int>(std::floor(coords.x / 2.0f));

if (ry < offset) {
if ((m_index == CellIndex::Even) == (parity(y) == 0)) {
if (parity(x) == 0) {
if (nrx > nry) {
--coords.y;
++coords.x;
}
} else {
coords.x = static_cast<int>((position.x - m_tileSize.width / 2) / m_tileSize.width);
if (nrx + nry < 1) {
--coords.y;
}
}
break;
case CellIndex::Even:
if (coords.y % 2 != 0) {
coords.x = static_cast<int>(position.x / m_tileSize.width);
} else {
if (parity(x) == 0) {
if (nrx + nry < 1) {
--coords.y;
--coords.x;
}
} else {
coords.x = static_cast<int>((position.x - m_tileSize.width / 2) / m_tileSize.width);
if (nrx > nry) {
--coords.y;
}
}
break;
}
}

break;
}
}

return coords;
Expand Down
2 changes: 1 addition & 1 deletion library/core/Cells_Orthogonal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ inline namespace v1 {
}

Vector2i OrthogonalCells::computeCoordinates(Vector2f position) const noexcept {
return position / m_tileSize;
return vec(static_cast<int>(std::floor(position.x / m_tileSize.width)), static_cast<int>(std::floor(position.y / m_tileSize.height)));
}

Polyline OrthogonalCells::computePolyline(Vector2i coords) const {
Expand Down
22 changes: 8 additions & 14 deletions library/core/Cells_Staggered.cc
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,6 @@ inline namespace v1 {
return RectF::fromPositionSize(base, m_tileSize);
}

namespace {

bool isDiagonallySplit(CellIndex index, int x, int y) {
return (index == CellIndex::Even) == (parity(x) == parity(y));
}

}

Vector2i StaggeredCells::computeCoordinates(Vector2f position) const noexcept {
const Vector2f half = m_tileSize / 2.0f;

Expand All @@ -116,26 +108,28 @@ inline namespace v1 {

gf::Vector2i coords = vec(x, y);

const bool isDiagonallySplit = (m_index == CellIndex::Even) == (parity(x) == parity(y));

if (m_axis == CellAxis::X) {
if ((isDiagonallySplit(m_index, x, y) && rx < ry) || (!isDiagonallySplit(m_index, x, y) && (rx + ry) < 1)) {
if ((isDiagonallySplit && rx < ry) || (!isDiagonallySplit && (rx + ry) < 1)) {
--coords.x;
}

coords.y = y / 2;
coords.y = static_cast<int>(std::floor(qy / 2));

if (parity(y) == 0 && ((isDiagonallySplit(m_index, x, y) && rx > ry) || (!isDiagonallySplit(m_index, x, y) && (rx + ry) < 1))) {
if (parity(y) == 0 && ((isDiagonallySplit && rx > ry) || (!isDiagonallySplit && (rx + ry) < 1))) {
--coords.y;
}

// Log::info("position: %g %g\tq: %g %g\tr: %g %g\tcoords: %d %d\n", position.x, position.y, qx, qy, rx, ry, coords.x, coords.y);
} else {
if ((isDiagonallySplit(m_index, x, y) && rx > ry) || (!isDiagonallySplit(m_index, x, y) && (rx + ry) < 1)) {
if ((isDiagonallySplit && rx > ry) || (!isDiagonallySplit && (rx + ry) < 1)) {
--coords.y;
}

coords.x = x / 2;
coords.x = static_cast<int>(std::floor(qx / 2));

if (parity(x) == 0 && ((isDiagonallySplit(m_index, x, y) && rx < ry) || (!isDiagonallySplit(m_index, x, y) && (rx + ry) < 1))) {
if (parity(x) == 0 && ((isDiagonallySplit && rx < ry) || (!isDiagonallySplit && (rx + ry) < 1))) {
--coords.x;
}
}
Expand Down

0 comments on commit fc0c958

Please sign in to comment.