admin管理员组

文章数量:1292699

A JavaScript question.

Below is a routine that seems to have some problems. What is the problem? The function, given two points, is supposed to return the angle (in radians) formed between the horizontal axis and the line containing the two points (X1,Y1) and (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;
}

A JavaScript question.

Below is a routine that seems to have some problems. What is the problem? The function, given two points, is supposed to return the angle (in radians) formed between the horizontal axis and the line containing the two points (X1,Y1) and (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;
}
Share Improve this question asked Aug 29, 2011 at 20:50 Jim AndrewsJim Andrews 551 silver badge4 bronze badges 1
  • 1 and... what's the problem? The error message it gives? The angle you get when you execute it? – woliveirajr Commented Aug 29, 2011 at 20:55
Add a ment  | 

3 Answers 3

Reset to default 9

Why don't you use Math.atan2, which is more convenient. It automatically does it right when both numbers are negative (which information is lost with dividing), and returns the correct values for edge cases as well.

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

The function is calculating the inverse of the tangent.

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

But it is preferred to use Math.atan2(), as pimvdb has mentioned.

Thanks for the help! I did try atan2 but it didn't work right in some situations. I wrote my own function to handle this issue. Here it is. Works great.

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
    }

本文标签: javascriptCalculating the angle between the horizontal and a line through two pointsStack Overflow