Получить угол с 2 позиций - PullRequest
20 голосов
/ 20 мая 2011

У меня есть 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 градусов и т. Д.

Ответы [ 5 ]

44 голосов
/ 20 мая 2011

Помогает ли этот другой ответ?

Как сопоставить atan2 () с градусами 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.

Надеюсь, это поможет.

12 голосов
/ 10 июля 2012

Я изменил решение @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 источник. Таким образом вычитая p0 из p1 (p0 - p0 = {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() тогда ты должен сделать это.

10 голосов
/ 16 октября 2015

Вот как я делаю это в Swift для тех, кто заинтересован, он основан на ответе @ bshirley, приведенном выше, с несколькими модификациями, чтобы помочь соответствовать системе вращения калибровочных:

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

Это обеспечивает координатусистема, подобная этой:

        270
180              0
        90

Использование:

point.angle(to: point2)
CGPoint.zero.angle(to: CGPoint(x: 0, y: 1)) // 90
1 голос
/ 20 мая 2011

Угол между двумя точками отсутствует.Если вы хотите узнать угол между векторами от начала координат (0,0) до объектов, используйте скалярное (точечное) произведение:

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

Математическая библиотека std используемого вами языка навернякапредоставляет функции для arcus cosine, скалярного произведения и длины.

0 голосов
/ 17 января 2019

Вершина угла - это точка (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)) )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...