曼哈顿 六边形网格中瓷砖之间的距离

发布于 2024-10-18 13:34:47 字数 334 浏览 3 评论 0原文

对于方形网格,图块 A 和 B 之间的欧几里德距离为:

distance = sqrt(sqr(x1-x2)) + sqr(y1-y2))

对于被限制沿方形网格移动的演员,曼哈顿距离是我们必须行进的实际距离的更好衡量标准:

manhattanDistance = abs(x1-x2) + abs(y1-y2))

如何获取两个图块之间的曼哈顿距离如下图红线和蓝线所示的六边形网格?

在此处输入图像描述

For a square grid the euclidean distance between tile A and B is:

distance = sqrt(sqr(x1-x2)) + sqr(y1-y2))

For an actor constrained to move along a square grid, the Manhattan Distance is a better measure of actual distance we must travel:

manhattanDistance = abs(x1-x2) + abs(y1-y2))

How do I get the manhattan distance between two tiles in a hexagonal grid as illustrated with the red and blue lines below?

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

孤檠 2024-10-25 13:34:47

我曾经在游戏中设置了一个六边形坐标系,使 y 轴与 x 轴成 60 度角。这避免了奇偶行的区别。

六角网格
(来源:althenia.net)< /sub>

此坐标系中的距离为:

dx = x1 - x0
dy = y1 - y0

if sign(dx) == sign(dy)
    abs(dx + dy)
else
    max(abs(dx), abs(dy))

您可以将 (x', y) 从您的坐标系转换为 (x, < em>y) 在这一点中使用:

x = x' - floor(y/2)

因此 dx 变为:

dx = x1' - x0' - floor(y1/2) + floor(y0/2)

使用整数除法实现此操作时请小心舍入。在 C 中,int y floor(y/2)(y%2 ? y-1 : y)/2

I once set up a hexagonal coordinate system in a game so that the y-axis was at a 60-degree angle to the x-axis. This avoids the odd-even row distinction.

Hexagonal grid
(source: althenia.net)

The distance in this coordinate system is:

dx = x1 - x0
dy = y1 - y0

if sign(dx) == sign(dy)
    abs(dx + dy)
else
    max(abs(dx), abs(dy))

You can convert (x', y) from your coordinate system to (x, y) in this one using:

x = x' - floor(y/2)

So dx becomes:

dx = x1' - x0' - floor(y1/2) + floor(y0/2)

Careful with rounding when implementing this using integer division. In C for int y floor(y/2) is (y%2 ? y-1 : y)/2.

简单 2024-10-25 13:34:47

我假设您想要如图所示识别的两个图块中心之间的平面中的欧几里得距离。我想这可以从图中推导出来。对于任何 x 和 y,从图块 (x, y) 的中心到图块 (x + dx, y) 的中心的向量为 (dx, 0)。从图块 (x, y) 和 (x, y + dy) 中心出发的向量为 (-dy / 2, dy*sqrt(3) / 2)。对于任何 x、y、dx,简单的向量加法给出 (x, y) 和 (x + dx, y + dy) 之间的 (dx - (dy / 2), dy * sqrt(3) / 2) 向量,和迪。总距离就是向量的范数: sqrt((dx - (dy / 2)) ^ 2 + 3 * dy * dy / 4)

I assume that you want the Euclidean distance in the plane between the centers of two tiles that are identified as you showed in the figure. I think this can be derived from the figure. For any x and y, the vector from the center of tile (x, y) to the center of tile (x + dx, y) is (dx, 0). The vector from the center of tile (x, y) and (x, y + dy) is (-dy / 2, dy*sqrt(3) / 2). A simple vector addition gives a vector of (dx - (dy / 2), dy * sqrt(3) / 2) between (x, y) and (x + dx, y + dy) for any x, y, dx, and dy. The total distance is then the norm of the vector: sqrt((dx - (dy / 2)) ^ 2 + 3 * dy * dy / 4)

多彩岁月 2024-10-25 13:34:47

如果你想要直线距离:

double dy = y2 - y1;
double dx = x2 - x1;
// if the height is odd
if ((int)dy & 1){
    // whether the upper x coord is displaced left or right
    // depends on whether the y1 coordinate is odd
    dx += ((y1 & 1) ? -0.5 : 0.5);
}
double dis = sqrt(dx*dx + dy*dy);

我想说的是,如果dy是偶数,它只是一个矩形空间。如果dy为奇数,则右上角的位置向左或向右1/2个单位。

If you want the straight-line distance:

double dy = y2 - y1;
double dx = x2 - x1;
// if the height is odd
if ((int)dy & 1){
    // whether the upper x coord is displaced left or right
    // depends on whether the y1 coordinate is odd
    dx += ((y1 & 1) ? -0.5 : 0.5);
}
double dis = sqrt(dx*dx + dy*dy);

What I'm trying to say is, if dy is even, it's just a rectangular space. If dy is odd, the position of the upper right corner is 1/2 unit to the left or to the right.

静水深流 2024-10-25 13:34:47

对这个问题的直接回答是不可能的。这个问题的答案与你如何在内存中组织图块有很大关系。我使用 odd-q 垂直布局,并使用以下 matlab 代码始终给我正确的答案。

function f = offset_distance(x1,y1,x2,y2)
    ac = offset_to_cube(x1,y1);
    bc = offset_to_cube(x2,y2);
    f = cube_distance(ac, bc);
end

function f = offset_to_cube(row,col)
    %x = col - (row - (row&1)) / 2;
    x = col - (row - mod(row,2)) / 2;
    z = row;
    y = -x-z;
    f = [x,z,y];
end

function f= cube_distance(p1,p2)
    a = abs( p1(1,1) - p2(1,1));
    b = abs( p1(1,2) - p2(1,2));
    c = abs( p1(1,3) - p2(1,3));
    f =  max([a,b,c]);
end

这是一个 matlab 测试代码

sx = 6;
sy = 1;
for i = 0:7
    for j = 0:5
        k = offset_distance(sx,sy,i,j);
        disp(['(',num2str(sx),',',num2str(sy),')->(',num2str(i),',',num2str(j),')=',num2str(k)])
    end
end

有关此解决方案的数学详细信息,请访问:http://www.redblobgames.com /网格/六边形/ 。您可以在以下位置获取完整的 hextile 库: http://www.redblobgames.com/grids /hexagons/implementation.html

A straight forward answer for this question is not possible. The answer of this question is very much related to how you organize your tiles in the memory. I use odd-q vertical layout and with the following matlab code gives me the right answer always.

function f = offset_distance(x1,y1,x2,y2)
    ac = offset_to_cube(x1,y1);
    bc = offset_to_cube(x2,y2);
    f = cube_distance(ac, bc);
end

function f = offset_to_cube(row,col)
    %x = col - (row - (row&1)) / 2;
    x = col - (row - mod(row,2)) / 2;
    z = row;
    y = -x-z;
    f = [x,z,y];
end

function f= cube_distance(p1,p2)
    a = abs( p1(1,1) - p2(1,1));
    b = abs( p1(1,2) - p2(1,2));
    c = abs( p1(1,3) - p2(1,3));
    f =  max([a,b,c]);
end

Here is a matlab testing code

sx = 6;
sy = 1;
for i = 0:7
    for j = 0:5
        k = offset_distance(sx,sy,i,j);
        disp(['(',num2str(sx),',',num2str(sy),')->(',num2str(i),',',num2str(j),')=',num2str(k)])
    end
end

For mathematical details of this solution visit: http://www.redblobgames.com/grids/hexagons/ . You can get a full hextile library at: http://www.redblobgames.com/grids/hexagons/implementation.html

白日梦 2024-10-25 13:34:47

这听起来像是 Bresenham 线算法 的工作。您可以使用它来计算从 A 到 B 的路段数量,这将告诉您路径距离。

This sounds like a job for the Bresenham line algorithm. You can use that to count the number of segments to get from A to B, and that will tell you the path distance.

年华零落成诗 2024-10-25 13:34:47

如果将不同的六边形定义为图,则可以得到从节点 A 到节点 B 的最短路径。由于到六边形中心的距离是恒定的,因此将其设置为边权重。

不过,这对于大油田来说可能效率低下。

If you define the different hexagons as a graph, you can get the shortest path from node A to node B. Since the distance from the hexagon centers is constant, set that as the edge weight.

This will probably be inefficient for large fields though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文