【问题标题】:Get angle from 2 positions从 2 个位置获取角度
【发布时间】:2011-08-29 05:00:21
【问题描述】:

我有 2 个对象,当我移动一个时,我想从另一个获得角度。

例如:

Object1X = 211.000000, Object1Y = 429.000000
Object2X = 246.500000, Object2Y = 441.500000

我在阳光下尝试了以下各种变化:

double radians = ccpAngle(Object1,Object2);
double degrees = ((radians * 180) / Pi); 

但我只返回了 2.949023,我想要 45 度等。

【问题讨论】:

  • 什么点应该是角的顶点?假设原点,那么我得到两个对象之间的角度为 2.986 度。
  • [**如何从 2 个位置获取角度 **][1] [1]: stackoverflow.com/questions/9457988/…

标签: ios cocos2d-iphone


【解决方案1】:

这个其他答案有帮助吗?

How to map atan2() to degrees 0-360

我是这样写的:

- (CGFloat) pointPairToBearingDegrees:(CGPoint)startingPoint secondPoint:(CGPoint) endingPoint
{
    CGPoint originPoint = CGPointMake(endingPoint.x - startingPoint.x, endingPoint.y - startingPoint.y); // get origin point to origin by subtracting end from start
    float bearingRadians = atan2f(originPoint.y, originPoint.x); // get bearing in radians
    float bearingDegrees = bearingRadians * (180.0 / M_PI); // convert to degrees
    bearingDegrees = (bearingDegrees > 0.0 ? bearingDegrees : (360.0 + bearingDegrees)); // correct discontinuity
    return bearingDegrees;
}

运行代码:

CGPoint p1 = CGPointMake(10, 10);
CGPoint p2 = CGPointMake(20,20);

CGFloat f = [self pointPairToBearingDegrees:p1 secondPoint:p2];

这会返回 45。

希望这会有所帮助。

【讨论】:

  • 那行得通,我相信我昨晚所做的一切都会奏效。原来我是从光标的位置而不是对象的位置来计算的,所以这就是为什么我认为我的读数是错误的。哎呀。感谢您的帮助
  • 意识到错误是成功的一半!
  • 爱你回答,但需要说的是,对于你的函数,已有cocos方法: //瞄准枪 float radians = atan2(self.position.y-crosshairPosition.y, crosshairPosition .x-self.position.x);浮动度= CC_RADIANS_TO_DEGREES(弧度); gun.rotation = 度数;
  • 这搞砸了代码,但我认为你可以弄清楚它是什么。得到 atan2 后,您可以直接转换为 CC_RADIANS_TO_DEGREE。背后的方法是你自己写的。
  • 这是正确的答案。接受的返回一个奇怪的角度值。
【解决方案2】:

对于那些感兴趣的人来说,这是我在 Swift 中的做法,它基于上面@bshirley 的回答,并进行了一些修改以帮助匹配 calayer 旋转系统:

extension CGFloat {
    var degrees: CGFloat {
        return self * CGFloat(180) / .pi
    }
}

extension CGPoint {
    func angle(to comparisonPoint: CGPoint) -> CGFloat {
        let originX = comparisonPoint.x - x
        let originY = comparisonPoint.y - y
        let bearingRadians = atan2f(Float(originY), Float(originX))
        var bearingDegrees = CGFloat(bearingRadians).degrees

        while bearingDegrees < 0 {
            bearingDegrees += 360
        }

        return bearingDegrees
    }
}

这提供了一个这样的坐标系:

        90
180              0
        270

用法:

point.angle(to: point2)
CGPoint.zero.angle(to: CGPoint(x: 0, y: 1)) // 90

【讨论】:

  • 如何在 swift 3 中实现这一点
  • @UmaMadhavi 稍微更新了答案,您只需要一个外部参数,但我让它符合新的设计准则?
  • 在 point & point2 的地方我如何发送纬度和经度值。
  • @UmaMadhavi 需要基于地球曲率和坐标系的不同数学。我认为这个问题更适用于:stackoverflow.com/questions/26998029/…
【解决方案3】:

我修改了@tomas 的解决方案以进行简化。很可能(对我来说)这个数学会被频繁调用。

在我的化身中,您必须自己执行两点之间的差值(或者如果幸运的话,(0,0)已经是您的点之一)。正在计算的值是从 (0,0) 开始的点的方向。是的,这很简单,如果你真的想的话,你可以内联它。我更喜欢可读性更高的代码。

我也将其转换为函数调用:

CGFloat CGPointToDegree(CGPoint point) {
  // Provides a directional bearing from (0,0) to the given point.
  // standard cartesian plain coords: X goes up, Y goes right
  // result returns degrees, -180 to 180 ish: 0 degrees = up, -90 = left, 90 = right
  CGFloat bearingRadians = atan2f(point.y, point.x);
  CGFloat bearingDegrees = bearingRadians * (180. / M_PI);
  return bearingDegrees;
}

如果您不想要负值,则需要自己进行转换。负值对我来说很好 - 无需进行不必要的计算。

我在 cocos2d 环境中使用它,这就是我所说的:(数学上,我们正在平移平面以使 p0 成为原点。因此从 p1 中减去 p0 (p0 - @ 987654327@ = {0,0})。平面平移时角度不变。)

CGPoint p0 = self.position;
CGPoint p1 = other.position;
CGPoint pnormal = ccpSub(p1, p0);
CGFloat angle = CGPointToDegree(pnormal);

ccpSub 由 cocos2d 提供,它是一个元组的减法 - 如果你没有可用的,你可以自己做

除此之外:使用CG___ 命名方案将方法标识为CoreGraphics 的一部分通常是不礼貌的风格,因此如果您想将其重命名为MyConvertCGPointToBearing()FredLovesWilma()那么你应该这样做。

【讨论】:

  • 你应该用atan2f(point.y, point.x); 更正atan2f(point.x, point.y);(反转x 和y)
  • 感谢@Matter - (参考:manpagez.com/man/3/atan2f) - 已修复。
【解决方案4】:

Tomas' answerSwift 5.1

func angle(between starting: CGPoint, ending: CGPoint) -> CGFloat {
    let center = CGPoint(x: ending.x - starting.x, y: ending.y - starting.y)
    let radians = atan2(center.y, center.x)
    let degrees = radians * 180 / .pi
    return degrees > 0 ? degrees : degrees + degrees
}

【讨论】:

    【解决方案5】:

    两点之间没有角度。如果您想知道从原点 (0,0) 到对象的向量之间的角度,请使用标量(点)积:

    theta = arccos ( (veca dot vecb) / ( |veca| * |vecb| )
    

    您使用的语言的数学标准库肯定提供了反余弦、标量积和长度的函数。

    【讨论】:

      【解决方案6】:

      角的顶点是点(0,0)。

      考虑 object1X=x1 ....object2Y=y2。

      Angle(object1-object2) = 
         90       * (  (1 + sign(x1)) * (1 - sign(y1^2))
                     - (1 + sign(x2)) * (1 - sign(y2^2)) )
       + 45       * (  (2 + sign(x1)) * sign(y1)
                     - (2 + sign(x2)) * sign(y2)         )
       + 180/pi() * sign(x1*y1) * atan( (abs(x1) - abs(y1)) / (abs(x1) + abs(y1)) )
       - 180/pi() * sign(x2*y2) * atan( (abs(x2) - abs(y2)) / (abs(x2) + abs(y2)) )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-15
        • 2016-07-28
        • 1970-01-01
        • 1970-01-01
        • 2016-10-28
        • 1970-01-01
        相关资源
        最近更新 更多