您也可以采用完全不同的方法解决此问题。您知道两个六边形的X / Y(笛卡尔坐标)坐标,这意味着您可以获得相对于六边形空间原点的每个六边形的立方坐标。两个六边形之间的距离简单地是两个六边形的X,Y和Z立方坐标之间的差的绝对值的总和。 (那是, dist = |h2.X - h1.X| + |h2.Y - h1.Y| + |h2.Z - h1.Z| )因此,不是试图计算两个中心点之间的矢量然后将其转换为立方坐标,您可以直接在立方坐标中计算距离(就像在笛卡尔坐标中这些是正方形一样)......
dist = |h2.X - h1.X| + |h2.Y - h1.Y| + |h2.Z - h1.Z|
但是,即使您采用这种方法,我强烈建议您使用原始方法调试正在进行的操作。即使您最终丢弃了代码,调试的练习也可能会教会您将来能够应用的宝贵课程。
读者注意:“立方”坐标不是三维笛卡尔坐标,它们是六边形专用坐标系,OP为其提供了链接。
这个事实 计算 (也就是说,从偏移到立方坐标的转换,以及立方坐标中距离的计算)似乎是正确的,这表明蒂姆对浮点误差的假设是正确的。
你应该尝试改变这条线
hexagon.setQR((int)deltaXRadius, (int)deltaYApothem);
从您的原始代码到类似的东西
hexagon.setQR((int)Math.round(deltaXRadius), (int)Math.round(deltaYApothem));
在这种情况下哪个可以解决问题。
如果不是......或者......在任何情况下,这里都是一个小例子,基本上和你一样,但作为一个MVCE ...
import java.awt.Point; public class HexagonsTest { public static void main(String[] args) { // Above and below test(8,6, 8,5, 1); test(8,6, 8,7, 1); // Left test(8,6, 7,5, 1); test(8,6, 7,6, 1); // Right test(8,6, 9,5, 1); test(8,6, 9,6, 1); // The first one that was wrong: test(8,6, 7,4, 2); } private static void test(int x0, int y0, int x1, int y1, int expected) { int distance = computeStepsDistance(x0, y0, x1, y1); System.out.println( "Distance of (" + x0 + "," + y0 + ") to " + "(" + x1 + "," + y1 + ") is " + distance + ", expected " + expected); } private static int computeStepsDistance(int x0, int y0, int x1, int y1) { Point cp0 = convertOffsetToCubeCoordinates(x0, y0, null); Point cp1 = convertOffsetToCubeCoordinates(x1, y1, null); int cx0 = cp0.x; int cy0 = cp0.y; int cz0 = -cx0-cy0; int cx1 = cp1.x; int cy1 = cp1.y; int cz1 = -cx1-cy1; int dx = Math.abs(cx0 - cx1); int dy = Math.abs(cy0 - cy1); int dz = Math.abs(cz0 - cz1); return Math.max(dx, Math.max(dy, dz)); } private static Point convertOffsetToCubeCoordinates( int ox, int oy, Point p) { int cx = ox; int cz = oy - (ox - (ox&1)) / 2; int cy = -cx-cz; if (p == null) { p = new Point(); } p.x = cx; p.y = cy; return p; } }