52 votes

Java : calcul de l'angle entre deux points en degrés

J'ai besoin de calculer l'angle en degrés entre deux points pour ma propre classe Point, le point a doit être le point central.

Méthode:

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

Test 1 : // renvoie 45

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

Test 2 : // renvoie -90, attendu : 270

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

Comment puis-je convertir le résultat renvoyé en un nombre compris entre 0 et 359 ?

88voto

johncarl Points 5449

vous pouvez ajouter les éléments suivants :

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

au fait, pourquoi ne voulez-vous pas utiliser de double ici ?

31voto

Joseph Snow Points 537

J'ai commencé avec la solution johncarls, mais je devais l'ajuster pour obtenir exactement ce dont j'avais besoin. Principalement, j'avais besoin qu'il tourne dans le sens des aiguilles d'une montre lorsque l'angle augmentait. J'avais aussi besoin de 0 degré pour pointer vers le NORD. Sa solution m'a rapproché, mais j'ai décidé de publier ma solution également au cas où cela aiderait quelqu'un d'autre.

J'ai ajouté quelques commentaires supplémentaires pour aider à expliquer ma compréhension de la fonction au cas où vous auriez besoin d'apporter des modifications simples.

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

2voto

Sur la base de la réponse de Saad Ahmed , voici une méthode qui peut être utilisée pour deux points quelconques.

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

1voto

Spencer Kormos Points 3082

Le javadoc pour Math.atan(double) est assez clair que la valeur de retour peut aller de -pi/2 à pi/2. Vous devez donc compenser cette valeur de retour.

0voto

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

maintenant pour l'orientation des valeurs circulaires pour garder l'angle entre 0 et 359 peut être :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X