【问题标题】:Calculate the distance between two CGPoints计算两个CGPoints之间的距离
【发布时间】:2011-06-20 19:04:38
【问题描述】:

我需要计算两个CGPoints 之间的距离。我参考了thisthis,但我不明白。

【问题讨论】:

  • 距离是一个标量值,不是一个点。
  • “CGPoint 中的距离”是什么意思?一个点代表一个无限小的位置。距离不能用点来衡量。两点之间有无穷多个点。

标签: iphone box2d


【解决方案1】:

好吧,还有你所指的东西,完整的代码在哪里:

CGPoint p2; //[1]
CGPoint p1;
//Assign the coord of p2 and p1...
//End Assign...
CGFloat xDist = (p2.x - p1.x); //[2]
CGFloat yDist = (p2.y - p1.y); //[3]
CGFloat distance = sqrt((xDist * xDist) + (yDist * yDist)); //[4]

距离是可变距离。

这里发生了什么:

  1. 所以首先我们提出两点...
  2. 然后我们找到点的 x 坐标之间的距离。
  3. 现在我们找到了 y 坐标之间的距离。
  4. 这些长度是三角形的两条边,实际上它们是腿,是时候找到斜边了,这意味着在重新计算 c^2 = a^2 + b^2 之后,我们得到斜边等于 sqrt( (xDist^2) + (yDist^2))。 xDist^2 = (xDist * xDist)。同样:yDist^2 = (yDist * yDist)

您不能真正将 CGPoint 设为距离,距离没有 x 和 y 分量。这只是 1 个数字。

如果您认为 CGPoint 是度量单位(例如英尺是度量单位),则不是。

【讨论】:

  • 数学中两点之间的距离为:d = sqrt ( (x2-x1)^2 + (y2-y1)^2 );和 ;在数学中我们有: ( x - y )^2 = xx - 2*xy + yy ;而不是 xx - y*y 。所以你的计算是错误的!还是我错了?
  • @Houcine: (x-y)^2 =/= (x^2 - y^2)。他们不一样。发布 Wolfram Alpha 链接不起作用,但如果您转到 Wolfram alpha 并在其中输入两个方程,您会发现存在差异。
  • 我的数学老师总是教我用 2 和 1 做简单的测试来仔细检查你的数学。使 X 2 和 Y 1: 2^2 - 1^2 = 4-1 = 3. (2-1)^2 = 1^2 = 1. 1 != 3,所以 (x-y)^2 != (x ^2 - y^2)
【解决方案2】:

我必须手动完成 10,000 次,所以我为它编写了一个函数并将它保存在我的个人库中,我总是在新程序开始时转储它,所以我忘记了它不是大炮。

- (float)distanceBetween:(CGPoint)p1 and:(CGPoint)p2
{
    return sqrt(pow(p2.x-p1.x,2)+pow(p2.y-p1.y,2));
}

所以你这样称呼它(假设你想知道你的手指移动了多远):

float moveDistance = [self distanceBetween:touchStart and:touchEnd];

这在移动功能中以及在滚动菜单中进行抽查时很有用:

if([self distanceBetween:touchStart and:touchAt] > 20*scalePoints)
    isItATap = FALSE;

在 touchesBegan 中设置“isItATap”为真,将上面的内容放在 touchesMoved 中,然后你知道玩家将手指移动得太远以至于触摸不能成为“点击”,所以你可以让它不选择玩家触摸的对象并且而是滚动对象。

至于比例,这应该取决于您是否有视网膜显示器以及您使用的设备尺寸(视网膜显示器除以 2,因为常规屏幕上的 5 个“点”物理距离为用户的手指感觉它会在视网膜显示屏上显示为 10 个“像素”,因为每个点都是 4 个像素,所以您最终会遇到玩家很难点击视网膜显示屏的情况(即一个共同的疏忽)

【讨论】:

  • 无论如何,redux,你的代码都不会正常工作。 return sqrt(pow(p2.x-p1.x,2)+pow(p2.y-p2.y,2)); 我敢肯定这应该是; return sqrt(pow(p2.x-p1.x,2)+pow(p2.y-p1.y,2));
  • 并且返回类型应该是 CGFloat,以便与 ARM64 很好地配合。
  • 迅速func distanceBetween(point p1:CGPoint, andPoint p2:CGPoint) -> CGFloat { return sqrt(pow((p2.x - p1.x), 2) + pow((p2.y - p1.y), 2)) }
  • 编译器可能会为您优化,但通常乘法比调用pow 更有效。由于这是一个经常使用的小型纯函数,因此将其作为 C 函数而不是 Objective-C 消息也会做得更好。
【解决方案3】:

听起来您可能想要从 p1 到 p2 的向量(或 差异)而不是距离。

const CGPoint p1 = {10, 10};
const CGPoint p2 = {510, 310};

const CGPoint diff = {p2.x - p1.x, p2.y - p1.y} // == (CGPoint){500, 300}

【讨论】:

    【解决方案4】:

    简答

    CGPoint p1, p2; // Having two points
    CGFloat distance = hypotf((p1.x-p2.x), (p1.y-p2.y));
    

    更长的解释

    如果您有两个点 p1p2 显然很容易找到它们的 heightwidth 之间的差异(例如 ABS(p1.x - p2.x)),但要找到您真正想要的距离的真实表示小边(H 下面)。

     p1
      |\  
      | \  
      |  \ H
      |   \
      |    \
      |_ _ _\
             p2
    

    谢天谢地,有一个内置宏:hypotf(或hypot for doubles):

    // Returns the hypothenuse (the distance between p1 & p2)
    CGFloat dist = hypotf((p1.x-p2.x), (p1.y-p2.y));
    

    (原reference

    【讨论】:

      【解决方案5】:

      在 Swift 中,您可以向 CGPoint 添加扩展:

      extension CGPoint {
          func distance(to point: CGPoint) -> CGFloat {
              return sqrt(pow((point.x - x), 2) + pow((point.y - y), 2))
          }
      }
      

      并像这样使用它:

      let distance = p1.distance(to: p2)
      

      【讨论】:

      • 最快捷的方法。应该是这个问题的答案。
      • 除非问题是在 Swift 可用之前提出的。所以 ObjC 的答案应该是被接受的。
      【解决方案6】:

      在 Apple 的示例项目中,他们使用了 hypot。如answer 中所述,这将返回两点之间的假设(距离)。

      extension CGPoint {
      
          func distance(from point: CGPoint) -> CGFloat {
              return hypot(point.x - x, point.y - y)
          }
      }
      

      【讨论】:

        【解决方案7】:

        只有这个……

            float distance = ccpLength(ccpSub(p1,p2));
        

        其中 p1 和 p2 是 CGPoint 的对象

        【讨论】:

        • 以上使用的是Cocos2D函数,不是iOS原生的。
        • 问题是关于 Box2d..所以基本上应用程序与 cocos2d 集成:P
        【解决方案8】:

        Swift 4、Swift 3 解决方案

         extension CGPoint {
                static func distanceBetween(point p1: CGPoint,
                                            andPoint p2: CGPoint) -> CGFloat {
                    return sqrt(pow((p2.x - p1.x), 2) + pow((p2.y - p1.y), 2))
                }
            }
        

        【讨论】:

          【解决方案9】:
          extension CGPoint {
              func magnitude() -> CGFloat {
                  return sqrt(x * x + y * y)
              }
              
              func distance(to: CGPoint) -> CGFloat {
                  return CGPoint(x: to.x - x, y: to.y - y).magnitude()
              }
          }
          

          【讨论】:

            【解决方案10】:

            欧几里得距离使用 Vision api 到另一个点。

            iOS 14 开始。

            
            import Vision
            
            extension CGPoint {
                    
                public func distance(to point: CGPoint) -> Double {
                    VNPoint(location: self).distance(VNPoint(location: point))
                }
            }
            
            
            print(CGPoint(x: 1, y: 1).distance(to: .zero)) // 1.4142135623730951
            
            

            【讨论】:

              【解决方案11】:

              我扩展了上面的函数来计算两个 CGRect 之间的距离。我通过计算两个 CGRect 的角之间的距离然后返回最小距离来计算它。我从以下位置复制了两条线之间的函数计数交点:

              func distanceBetweenRectangles(r1: CGRect, r2: CGRect) -> CGFloat { // returns distance between boundaries of two rectangles or -1 if they intersect
                  let cornerPointsR1: [CGPoint] = [
                      CGPoint(x: r1.minX, y: r1.minY),CGPoint(x: r1.minX, y: r1.maxY),CGPoint(x: r1.maxX, y: r1.minY),CGPoint(x: r1.maxX, y: r1.maxY)]
                  let cornerPointsR2: [CGPoint] = [
                      CGPoint(x: r2.minX, y: r2.minY),CGPoint(x: r2.minX, y: r2.maxY),CGPoint(x: r2.maxX, y: r2.minY),CGPoint(x: r2.maxX, y: r2.maxY)]
                  for i in 0..<cornerPointsR1.count {
                      if (r2.contains(cornerPointsR1[i])) {
                          return -1
                      }
                  }        
                  var distances: [CGFloat] = []
                  for i in 0..<cornerPointsR1.count {
                      for j in 0..<cornerPointsR2.count {
                          distances.append(distanceBetweenPoints(p1: cornerPointsR1[i], p2: cornerPointsR2[j]))
                      }
                  }
                  distances.sort()
                  return distances[0]
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2021-05-15
                • 2021-01-14
                • 2010-10-30
                • 1970-01-01
                • 2020-02-12
                • 2019-02-16
                相关资源
                最近更新 更多