Tôi đã trả lời một câu hỏi tương tự, với các mục tiêu giống hệt nhau, trên Stack Overflow Tôi sẽ đăng lại nó ở đây để đảm bảo: (NB - tất cả mã được viết và kiểm tra bằng Java)
Hình ảnh này cho thấy góc trên cùng bên trái của lưới hình lục giác và được phủ lên là lưới hình vuông màu xanh. Thật dễ dàng để tìm ra điểm nào của hình vuông bên trong và điều này sẽ đưa ra một xấp xỉ thô về hình lục giác nào. Các phần màu trắng của hình lục giác hiển thị nơi lưới hình vuông và hình lục giác có cùng tọa độ và các phần màu xám của hình lục giác hiển thị ở nơi chúng không có.
Giải pháp bây giờ đơn giản như tìm một điểm nằm trong ô nào, sau đó kiểm tra xem điểm đó có nằm trong một trong ba hình tam giác hay không và sửa câu trả lời nếu cần.
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);
Tại thời điểm này, chúng ta có hàng và cột của hộp, điểm tiếp theo của chúng ta, tiếp theo chúng ta cần kiểm tra điểm của chúng ta dựa vào hai cạnh trên của hình lục giác để xem điểm của chúng ta có nằm trong một trong các hình lục giác ở trên không:
// 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);
Có tọa độ tương đối làm cho bước tiếp theo dễ dàng hơn.
Giống như trong hình trên, nếu y của điểm của chúng tôi là > mx + c, chúng tôi biết điểm của chúng tôi nằm phía trên đường thẳng và trong trường hợp của chúng tôi, hình lục giác ở trên và bên trái của hàng và cột hiện tại. Lưu ý rằng hệ tọa độ trong java có y bắt đầu từ 0 ở phía trên bên trái màn hình chứ không phải phía dưới bên trái như thông thường trong toán học, do đó gradient âm được sử dụng cho cạnh trái và gradient dương được sử dụng cho bên phải.
// 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];
}
Giải thích nhanh về các biến được sử dụng trong ví dụ trên:
m là độ dốc, vì vậy m = c / HalfWidth
Đây là phần phụ lục cho câu trả lời của SebastianTroy. Tôi sẽ để nó như một bình luận nhưng tôi chưa đủ danh tiếng.
Nếu bạn muốn triển khai một hệ tọa độ trục như được mô tả ở đây:
http://www.redblobgames.com/grids/hexagons/
Bạn có thể thực hiện một sửa đổi nhỏ cho mã.
Thay vì
// 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);
dùng cái này
float columnOffset = row * halfWidth;
column = (int)(x + columnOffset)/gridWidth; //switch + to - to align the grid the other way
Điều này sẽ làm cho tọa độ (0, 2) nằm trên cùng một cột đường chéo là (0, 0) và (0, 1) thay vì trực tiếp bên dưới (0, 0).