代码之家  ›  专栏  ›  技术社区  ›  Justin L.

环面缠绕(x和y缠绕)地图上点之间的最短距离?

  •  13
  • Justin L.  · 技术社区  · 15 年前

    基本上,点的绘制基于:* 请参见编辑

    (x_new, y_new) = ( x_old % width, y_old % height)
    

    想想吃豆人——离开屏幕的一边会让你出现在另一边。

    计算两点间最短距离的最佳方法是什么?典型的实现建议在地图的对角点有一个较大的距离,而实际上,实际的包裹距离非常接近。

    我能想到的最好的方法是计算经典的Delta X和包裹的Delta X,以及经典的Delta Y和包裹的Delta Y,并使用Sqrt(X^2+Y^2)距离公式中每对中的较低者。

    但这将涉及许多检查、计算和操作——我觉得有些可能是不必要的。

    有更好的办法吗?


    7 回复  |  直到 15 年前
        1
  •  13
  •   David Z    13 年前

    我能想到的最好的方法是计算经典的Delta X和包裹的Delta X,以及经典的Delta Y和包裹的Delta Y,并使用Sqrt(X^2+Y^2)距离公式中每对中的较低者。

    就这样,我想没有更快的办法了。但计算起来并不难;你可以这样做

    dx = abs(x1 - x2);
    if (dx > width/2)
      dx = width - dx;
    // again with x -> y and width -> height
    

    (我相信你能把它翻译成你喜欢的语言)

        2
  •  4
  •   GreenEye    13 年前

        dx = x2-x1
        dx = dx - x_width*ANINT(dx/x_width)
    

    这将给出一个有符号的最短距离。ANINT是一个内在的FORTRAN函数,使得ANINT(x)给出最接近的整数

        3
  •  3
  •   namin    15 年前

    a -带值的新坐标轴 a1 a2 ,在哪里 aBoundary 边界在

    def delta(a1, a2, aBoundary):
      return min(abs(a2 - a1), abs(a2 + aBoundary - a1))
    

    如果你有两个点有新的坐标 x1,y1 x2,y2

    sumOfSquares(delta(x1,x2,width), delta(y1,y2,height))
    

    这实际上是你所建议的,但我不会说这是“许多检查、计算和操作”。

        4
  •  0
  •   zerm    15 年前

    任何距离都不能大于width/2和height/2。如果得到的差值(X1-X2)大于width/2,则减去width/2以获得捷径距离。然后照常计算距离。

        5
  •  0
  •   MSN    15 年前
    (delta_x, delta_y)= 
         (min(width - abs(x_new - x_new), abs(x_new - x_old)), 
          min(height - abs(y_new - y_old), abs(y_new - y_old)))
    
        6
  •  0
  •   Matt O'Neill    10 年前

    我做了一些与众不同的事。。。

    有一点额外的功能在这里,但核心是一个包裹屏幕上的距离。。。

    from math import sqrt
    import pytweening
    
    class ClosestPoint_WD(object):
    def __init__(self, screen_size, point_from, point_to):
        self._width = screen_size[0]
        self._height = screen_size[1]
        self._point_from = point_from
        self._point_to = point_to
        self._points = {}
        self._path = []
    
    def __str__(self):
        value = "The dictionary:" + '\n'
        for point in self._points:
            value = value + str(point) + ":" + str(self._points[point]) + '\n'
    
        return value
    
    def distance(self, pos0, pos1):
        dx = pos1[0] - pos0[0]
        dy = pos1[1] - pos0[1]
        dz = sqrt(dx**2 + dy**2)
    
        return dz
    
    def add_point_to_dict(self, x, y):
        point = x, y
        self._points[point] = 0
    
    def gen_points(self):
        max_x = self._width * 1.5 - 1
        max_y = self._height * 1.5 - 1
    
        # point 1, original point
        self.add_point_to_dict(self._point_to[0], self._point_to[1])
    
        # add the second point: x-shifted
        if self._point_to[0] + self._width <= max_x:
            self.add_point_to_dict(self._point_to[0] + self._width, self._point_to[1])
        else:
            self.add_point_to_dict(self._point_to[0] - self._width, self._point_to[1])
    
        # add the third point: y-shifted
        if self._point_to[1] + self._height <= max_y:
            self.add_point_to_dict(self._point_to[0], self._point_to[1] + self._height)
        else:
            self.add_point_to_dict(self._point_to[0], self._point_to[1] - self._height)
    
        # add the fourth point: diagonally shifted
        if self._point_to[0] + self._width <= max_x:
            if self._point_to[1] + self._height <= max_y:
                self.add_point_to_dict(self._point_to[0] + self._width, self._point_to[1] + self._height)
            else:
                self.add_point_to_dict(self._point_to[0] + self._width, self._point_to[1] - self._height)
        else:
            if self._point_to[1] + self._height <= max_y:
                self.add_point_to_dict(self._point_to[0] - self._width, self._point_to[1] + self._height)
            else:
                self.add_point_to_dict(self._point_to[0] - self._width, self._point_to[1] - self._height)
    
    def calc_point_distances(self):
        for point in self._points:
            self._points[point] = self.distance(self._point_from, point)
    
    def closest_point(self):
        d = self._points
        return min(d, key=d.get)
    
    def update(self, cur_pos, target):
        self._point_from = cur_pos
        self._point_to = target
        self._points = {}
        self.gen_points()
        self.calc_point_distances()
        self.shortest_path()
    
    def shortest_path(self):
        path = pytweening.getLine(self._point_from[0], self._point_from[1], self.closest_point()[0], self.closest_point()[1])
        #path = pytweening.getLine((self._point_from)
        ret_path = []
    
        for point in path:
            ret_path.append((point[0] % self._width, point[1] % self._height))
    
        self._path = ret_path
        return self._path
    
        7
  •  -1
  •   Waleed A.K.    15 年前

    你不能在mod操作符中使用abs功能!

    xd =(x1-x2+Width)%Width
    yd=(y1-y2+Height)%Height
    D=sqrt(xd^2+yd^2)