ios 从 2 个位置获取角度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6064630/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:01:25  来源:igfitidea点击:

Get angle from 2 positions

ioscocos2d-iphone

提问by Jonathan Ogle-Barrington

I have 2 objects and when I move one, I want to get the angle from the other.

我有两个物体,当我移动一个物体时,我想从另一个物体获得角度。

For example:

例如:

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

I have tried the following and every variation under the sun:

我在阳光下尝试了以下和每一个变化:

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

But I just get 2.949023 returned where I want something like 45 degrees etc.

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

回答by Tomas McGuinness

Does this other answer help?

这个其他答案有帮助吗?

How to map atan2() to degrees 0-360

如何将 atan2() 映射到 0-360 度

I've written it like this:

我是这样写的:

- (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;
}

Running the code:

运行代码:

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

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

And this returns 45.

这将返回 45。

Hope this helps.

希望这可以帮助。

回答by bshirley

I modified @tomas' solution to be streamlined. It's likely (it was for me) that this math is going to be called frequently.

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

In my incarnation, you have to perform the difference between the two points yourself (or if you're lucky, (0,0) is already one of your points). The value being calculated is the direction of the point from (0,0). Yes, that's simple enough and you could inline it if you really want to. My preference is for more readable code.

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

I also converted it to a function call:

我还将它转换为函数调用:

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;
}

If you don't want negative values, you need to convert it yourself. Negative values were fine for me - no need to make unneeded calculations.

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

I was using this in a cocos2d environment, this is how I call it: (Mathematically, we are translating the plane to make p0the origin. Thus subtracting p0from p1(p0- p0= {0,0}). The angles are unchanged when the plane is translated.)

我是在一个cocos2d的环境中使用这个,这是我怎么称呼它:(数学上,我们所翻译的平面,使p0原点因此减去。p0p1p0- p0= {0,0})的角度不变时,飞机是。翻译。)

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

ccpSubis provided by cocos2d, it's subtraction of a tuple - you can do that yourself if you don't have that available

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

aside: it's generally not polite style to name the method as above with the CG___naming scheme, which identifies the function as part of CoreGraphics- so if you want to rename it to MyConvertCGPointToBearing()or FredLovesWilma()then you should do that.

旁白:使用CG___命名方案命名上述方法通常不是礼貌的风格,它将函数标识为的一部分CoreGraphics- 所以如果你想将它重命名为MyConvertCGPointToBearing()或者FredLovesWilma()你应该这样做。

回答by Logan

Here's how I'm doing it in Swift for those interested, it's based on @bshirley's answer above w/ a few modifications to help match to the calayer rotation system:

以下是我在 Swift 中为那些感兴趣的人所做的,它基于 @bshirley 上面的回答,并进行了一些修改以帮助匹配 calayer 轮换系统:

extension CGPoint {
    func angle(to comparisonPoint: CGPoint) -> CGFloat {
        let originX = comparisonPoint.x - self.x
        let originY = comparisonPoint.y - self.y
        let bearingRadians = atan2f(Float(originY), Float(originX))
        var bearingDegrees = CGFloat(bearingRadians).degrees
        while bearingDegrees < 0 {
            bearingDegrees += 360
        }
        return bearingDegrees
    }
}

extension CGFloat {
    var degrees: CGFloat {
        return self * CGFloat(180.0 / M_PI)
    }
}

This provides a coordinate system like this:

这提供了一个坐标系,如下所示:

        270
180              0
        90

Usage:

用法:

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

回答by vauxhall

Tomas' answerin Swift 5.1

托马斯Swift 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
}

回答by Hyperboreus

There is no angle between two points. If you want to know the angle between the vectors from the origin (0,0) to the objects, use the scalar (dot) product:

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

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

The math std lib of the language your are using surely provides functions for arcus cosine, scalar product and length.

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

回答by theodore panagos

The vertex of the angle is the point (0,0).

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

Consider object1X=x1 ....object2Y=y2.

考虑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)) )