4 votes

Calculer l'angle entre l'horizontale et une ligne passant par deux points

Une question sur le JavaScript.

Voici une routine qui semble avoir quelques problèmes. Quel est le problème ? La fonction, étant donné deux points, est censée retourner l'angle (en radians) formé entre l'axe horizontal et la ligne contenant les deux points (X1,Y1) et (X2,Y2).

function GetAngle(X1, Y1, X2, Y2) {
    if (Y2 == Y1) {
        return (X1 > X2) ? Math.PI : 0; 
    }
    if (X2 == X1) {
        return (Y2 > Y1) ? Math.PI/2 : 1.5*Math.PI;
    }
    var tangent = (X2 - X1) / (Y2 - Y1);
    var ang = Math.atan(tangent);
    if (Y2-Y1 < 0) ang -= Math.PI;
    return ang;
}

9voto

pimvdb Points 66332

Pourquoi n'utilisez-vous pas Math.atan2 ce qui est plus pratique. Il fait automatiquement ce qu'il faut lorsque les deux nombres sont négatifs (information qui est perdue avec la division), et renvoie les valeurs correctes pour les cas limites également.

var angle = Math.atan2(Y2 - Y1, X2 - X1);

// these return differently, even though 0 / -1 === 0 / 1
Math.atan2( 0, -1); // Math.PI
Math.atan2( 0,  1); // 0

// same thing: 1 / 1 === -1 / -1
Math.atan2( 1,  1); // Math.PI / 4
Math.atan2(-1, -1); // -Math.PI * 3 / 4

// other values
Math.atan2( 1,  1); // Math.PI / 4
Math.atan2( 1,  0); // Math.PI / 2
Math.atan2(-1,  0); // -Math.PI / 2

1voto

Mats Points 3039

La fonction calcule l'inverse de la tangente.

var tangent = (Y2 - Y1) / (X2 - X1);

Mais il est préférable d'utiliser Math.atan2() comme l'a mentionné pimvdb.

0voto

Jim Andrews Points 55

Merci pour votre aide ! J'ai essayé atan2 mais cela ne fonctionnait pas correctement dans certaines situations. J'ai écrit ma propre fonction pour gérer ce problème. La voici. Elle fonctionne très bien.

function calcAngle(p1, p2) {
        // Returns the angle points p1 and p2 form with the horizontal.
        if (p2.x > p1.x) {
            // quad 1 or 2
            if (p2.y > p1.y) {
                // quad 2
                return arctan(p1, p2)}
                // should be 1-90
            else {
                if (p2.y==p1.y) {
                    return 0}
                else {
                    // quad 1
                    return 2*Math.PI+arctan(p1, p2)
                    // 270-360
                }
            }
        }
        else {    
            if (p2.x==p1.x) {
                // atan undefined
                if (p2.y == p1.y) {
                    return 0}
                else {
                    if (p2.y > p1.y) {
                        return Math.PI/2}
                    else {
                        return 1.5*Math.PI
                    }
                }
            }
            else {
                // else { p2.x < p1.x
                // quad 3 or 4
                if (p2.y == p1.y) {
                    return Math.PI}
                else {
                    if (p2.y > p1.y) {
                        // quad 3
                        return Math.PI + arctan(p1, p2)}
                        // 90-180
                    else {
                        // quad 4
                        return Math.PI+ arctan(p1, p2)
                        // 180-270
                    }
                }
            }
        }
    }

    function arctan(p1, p2) {
        // Returns the arcTan of points p1 and p2.
        rat=  (p2.y-p1.y)/(p2.x-p1.x)
        inradians=Math.atan(rat)
        //indegrees=180*inradians/Math.PI
        return inradians
    }

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