web-dev-qa-db-ja.com

Java:2つのポイント間の角度を度で計算する

私は自分のPointクラスの2つのポイント間の角度を度数で計算する必要があります。ポイント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の数値に変換するにはどうすればよいですか?

44
Aich

以下を追加できます。

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を使用したくないのですか?

74
John Ericksen

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;
}
29
Joseph Snow

Saad Ahmed's answer に基づいて、2つのポイントに使用できる方法を次に示します。

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;
}
angle = Math.toDegrees(Math.atan2(target.x - x, target.y - y));

角度を0〜359に保つための円形値の方向は次のとおりです。

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

Math.atan(double) のjavadocは、戻り値の範囲が-pi/2〜pi/2の範囲であることを明確に示しています。そのため、その戻り値を補正する必要があります。

1
Spencer Kormos