Skip to content

Commit fc0c958

Browse files
committed
fix HexagonalCells::computeCoordinates
1 parent 441a356 commit fc0c958

File tree

5 files changed

+118
-44
lines changed

5 files changed

+118
-44
lines changed

examples/29_grid.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,15 @@ int main() {
118118
grids[current].grid.hover(renderer.mapPixelToCoords(event.mouseCursor.coords));
119119
break;
120120

121+
case gf::EventType::MouseButtonPressed:
122+
{
123+
auto coords = renderer.mapPixelToCoords(event.mouseButton.coords);
124+
auto localCoords = gf::transform(grids[current].grid.getInverseTransform(), coords);
125+
auto position = grids[current].grid.getCells().computeCoordinates(localCoords);
126+
std::cout << "Position: " << position.x << ',' << position.y << '\n';
127+
break;
128+
}
129+
121130
default:
122131
break;
123132
}

include/gf/Grid.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,13 @@ inline namespace v1 {
9292
*/
9393
static Grid createHexagonal(Vector2i gridSize, float radius, CellAxis axis, CellIndex index);
9494

95+
/**
96+
* @brief Get the underlying cells
97+
*/
98+
const Cells& getCells() const {
99+
return *m_properties;
100+
}
101+
95102
/**
96103
* @brief Set the grid size
97104
*

library/core/Cells_Hexagonal.cc

Lines changed: 93 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include <cassert>
2424

25+
#include <gf/Log.h>
2526
#include <gf/Span.h>
2627
#include <gf/VectorOps.h>
2728

@@ -116,50 +117,113 @@ inline namespace v1 {
116117
}
117118

118119
Vector2i HexagonalCells::computeCoordinates(Vector2f position) const noexcept {
119-
// good approximation but would need some tweaking
120-
121-
Vector2i coords = gf::vec(0, 0);
122120
float offset = computeOffset(m_tileSize, m_sideLength, m_axis);
121+
Vector2i coords = {};
123122

124123
switch (m_axis) {
125-
case CellAxis::X:
126-
coords.x = static_cast<int>(position.x / (m_tileSize.width - offset));
127-
switch (m_index) {
128-
case CellIndex::Odd:
129-
if (coords.x % 2 == 0) {
130-
coords.y = static_cast<int>(position.y / m_tileSize.height);
124+
case CellAxis::X: {
125+
const float lx = m_tileSize.width - offset;
126+
127+
const float qx = std::floor(position.x / lx);
128+
const float rx = position.x - qx * lx;
129+
const float nrx = rx / offset;
130+
131+
const float halfy = m_tileSize.height / 2.0f;
132+
const float qy = std::floor(position.y / halfy);
133+
const float ry = position.y - qy * halfy;
134+
const float nry = ry / halfy;
135+
136+
const int x = static_cast<int>(qx);
137+
const int y = static_cast<int>(qy);
138+
139+
coords = vec(x, y);
140+
141+
if ((m_index == CellIndex::Even) == (parity(x) == 0)) {
142+
--coords.y;
143+
}
144+
145+
coords.y = static_cast<int>(std::floor(coords.y / 2.0f));
146+
147+
if (rx < offset) {
148+
if ((m_index == CellIndex::Even) == (parity(x) == 0)) {
149+
if (parity(y) == 0) {
150+
if (nrx < nry) {
151+
--coords.x;
152+
++coords.y;
153+
}
131154
} else {
132-
coords.y = static_cast<int>((position.y - m_tileSize.height / 2) / m_tileSize.height);
155+
if (nrx + nry < 1) {
156+
--coords.x;
157+
}
133158
}
134-
break;
135-
case CellIndex::Even:
136-
if (coords.x % 2 != 0) {
137-
coords.y = static_cast<int>(position.y / m_tileSize.height);
159+
} else {
160+
if (parity(y) == 0) {
161+
if (nrx + nry < 1) {
162+
--coords.x;
163+
--coords.y;
164+
}
138165
} else {
139-
coords.y = static_cast<int>((position.y - m_tileSize.height / 2) / m_tileSize.height);
166+
if (nrx < nry) {
167+
--coords.x;
168+
}
140169
}
141-
break;
170+
}
142171
}
172+
143173
break;
144-
case CellAxis::Y:
145-
coords.y = static_cast<int>(position.y / (m_tileSize.height - offset));
146-
switch (m_index) {
147-
case CellIndex::Odd:
148-
if (coords.y % 2 == 0) {
149-
coords.x = static_cast<int>(position.x / m_tileSize.width);
174+
}
175+
176+
case CellAxis::Y: {
177+
const float ly = m_tileSize.height - offset;
178+
179+
const float qy = std::floor(position.y / ly);
180+
const float ry = position.y - qy * ly;
181+
const float nry = ry / offset;
182+
183+
const float halfx = m_tileSize.width / 2.0f;
184+
const float qx = std::floor(position.x / halfx);
185+
const float rx = position.x - qx * halfx;
186+
const float nrx = rx / halfx;
187+
188+
const int x = static_cast<int>(qx);
189+
const int y = static_cast<int>(qy);
190+
191+
coords = vec(x, y);
192+
193+
if ((m_index == CellIndex::Even) == (parity(y) == 0)) {
194+
--coords.x;
195+
}
196+
197+
coords.x = static_cast<int>(std::floor(coords.x / 2.0f));
198+
199+
if (ry < offset) {
200+
if ((m_index == CellIndex::Even) == (parity(y) == 0)) {
201+
if (parity(x) == 0) {
202+
if (nrx > nry) {
203+
--coords.y;
204+
++coords.x;
205+
}
150206
} else {
151-
coords.x = static_cast<int>((position.x - m_tileSize.width / 2) / m_tileSize.width);
207+
if (nrx + nry < 1) {
208+
--coords.y;
209+
}
152210
}
153-
break;
154-
case CellIndex::Even:
155-
if (coords.y % 2 != 0) {
156-
coords.x = static_cast<int>(position.x / m_tileSize.width);
211+
} else {
212+
if (parity(x) == 0) {
213+
if (nrx + nry < 1) {
214+
--coords.y;
215+
--coords.x;
216+
}
157217
} else {
158-
coords.x = static_cast<int>((position.x - m_tileSize.width / 2) / m_tileSize.width);
218+
if (nrx > nry) {
219+
--coords.y;
220+
}
159221
}
160-
break;
222+
}
161223
}
224+
162225
break;
226+
}
163227
}
164228

165229
return coords;

library/core/Cells_Orthogonal.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ inline namespace v1 {
4040
}
4141

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

4646
Polyline OrthogonalCells::computePolyline(Vector2i coords) const {

library/core/Cells_Staggered.cc

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,6 @@ inline namespace v1 {
9292
return RectF::fromPositionSize(base, m_tileSize);
9393
}
9494

95-
namespace {
96-
97-
bool isDiagonallySplit(CellIndex index, int x, int y) {
98-
return (index == CellIndex::Even) == (parity(x) == parity(y));
99-
}
100-
101-
}
102-
10395
Vector2i StaggeredCells::computeCoordinates(Vector2f position) const noexcept {
10496
const Vector2f half = m_tileSize / 2.0f;
10597

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

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

111+
const bool isDiagonallySplit = (m_index == CellIndex::Even) == (parity(x) == parity(y));
112+
119113
if (m_axis == CellAxis::X) {
120-
if ((isDiagonallySplit(m_index, x, y) && rx < ry) || (!isDiagonallySplit(m_index, x, y) && (rx + ry) < 1)) {
114+
if ((isDiagonallySplit && rx < ry) || (!isDiagonallySplit && (rx + ry) < 1)) {
121115
--coords.x;
122116
}
123117

124-
coords.y = y / 2;
118+
coords.y = static_cast<int>(std::floor(qy / 2));
125119

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

130124
// 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);
131125
} else {
132-
if ((isDiagonallySplit(m_index, x, y) && rx > ry) || (!isDiagonallySplit(m_index, x, y) && (rx + ry) < 1)) {
126+
if ((isDiagonallySplit && rx > ry) || (!isDiagonallySplit && (rx + ry) < 1)) {
133127
--coords.y;
134128
}
135129

136-
coords.x = x / 2;
130+
coords.x = static_cast<int>(std::floor(qx / 2));
137131

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

0 commit comments

Comments
 (0)