Java: вычисление угла между двумя точками в градусах - PullRequest
43 голосов
/ 02 апреля 2012

Мне нужно вычислить угол в градусах между двумя точками для моего собственного класса Point, точка a должна быть центральной точкой.

Метод:

public float getAngle(Point target) {
    return (float) Math.toDegrees(Math.atan2(target.x - x, target.y - y));
}

Тест 1: //возвращает 45

Point a = new Point(0, 0);
    System.out.println(a.getAngle(new Point(1, 1)));

Тест 2: // возвращает -90, ожидается: 270

Point a = new Point(0, 0);
    System.out.println(a.getAngle(new Point(-1, 0)));

Как я могу преобразовать полученный результат в число от 0 до 359?

Ответы [ 6 ]

73 голосов
/ 02 апреля 2012

Вы можете добавить следующее:

public float getAngle(Point target) {
    float angle = (float) Math.toDegrees(Math.atan2(target.y - y, target.x - x));

    if(angle < 0){
        angle += 360;
    }

    return angle;
}

кстати, почему вы не хотите использовать здесь двойное число?

27 голосов
/ 02 мая 2013

Я начал с решения johncarls, но мне нужно было его настроить, чтобы получить именно то, что мне нужно.В основном, мне нужно, чтобы он вращался по часовой стрелке, когда угол увеличивался.Мне также нужно было 0 градусов, чтобы указать север.Его решение приблизило меня, но я решил опубликовать свое решение и на тот случай, если оно кому-нибудь поможет.

Я добавил несколько дополнительных комментариев, чтобы объяснить мое понимание функции на случай, если вам нужно сделать простоемодификации.

/**
 * Calculates the angle from centerPt to targetPt in degrees.
 * The return should range from [0,360), rotating CLOCKWISE, 
 * 0 and 360 degrees represents NORTH,
 * 90 degrees represents EAST, etc...
 *
 * Assumes all points are in the same coordinate space.  If they are not, 
 * you will need to call SwingUtilities.convertPointToScreen or equivalent 
 * on all arguments before passing them  to this function.
 *
 * @param centerPt   Point we are rotating around.
 * @param targetPt   Point we want to calcuate the angle to.  
 * @return angle in degrees.  This is the angle from centerPt to targetPt.
 */
public static double calcRotationAngleInDegrees(Point centerPt, Point targetPt)
{
    // calculate the angle theta from the deltaY and deltaX values
    // (atan2 returns radians values from [-PI,PI])
    // 0 currently points EAST.  
    // NOTE: By preserving Y and X param order to atan2,  we are expecting 
    // a CLOCKWISE angle direction.  
    double theta = Math.atan2(targetPt.y - centerPt.y, targetPt.x - centerPt.x);

    // rotate the theta angle clockwise by 90 degrees 
    // (this makes 0 point NORTH)
    // NOTE: adding to an angle rotates it clockwise.  
    // subtracting would rotate it counter-clockwise
    theta += Math.PI/2.0;

    // convert from radians to degrees
    // this will give you an angle from [0->270],[-180,0]
    double angle = Math.toDegrees(theta);

    // convert to positive range [0-360)
    // since we want to prevent negative angles, adjust them now.
    // we can assume that atan2 will not return a negative value
    // greater than one partial rotation
    if (angle < 0) {
        angle += 360;
    }

    return angle;
}
2 голосов
/ 26 апреля 2017

Основываясь на ответе Саада Ахмеда , вот метод, который можно использовать для любых двух точек.

public static double calculateAngle(double x1, double y1, double x2, double y2)
{
    double angle = Math.toDegrees(Math.atan2(x2 - x1, y2 - y1));
    // Keep angle between 0 and 360
    angle = angle + Math.ceil( -angle / 360 ) * 360;

    return angle;
}
1 голос
/ 04 февраля 2015
angle = Math.toDegrees(Math.atan2(target.x - x, target.y - y));

теперь для ориентации круговых значений для сохранения угла между 0 и 359 можно:

angle = angle + Math.ceil( -angle / 360 ) * 360
1 голос
/ 02 апреля 2012

Javadoc для Math.atan (double) довольно ясно, что возвращаемое значение может варьироваться от -pi / 2 до pi / 2. Поэтому вам нужно компенсировать это возвращаемое значение.

0 голосов
/ 10 июня 2014

А что-то вроде:

angle = angle % 360;
...