Подтвердить что ты не робот

Java: вычисление угла между двумя точками в градусах

Мне нужно рассчитать угол в градусах между двумя точками для моего собственного класса 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?

4b9b3361

Ответ 1

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

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

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

Ответ 2

Я начал с решения 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;
}

Ответ 3

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

Ответ 4

Что-то вроде:

angle = angle % 360;

Ответ 5

angle = Math.toDegrees(Math.atan2(target.x - x, target.y - y));

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

angle = angle + Math.ceil( -angle / 360 ) * 360

Ответ 6

На основе Saad Ahmed answer, вот метод, который можно использовать для любых двух точек.

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