通过两点计算水平线和一条线之间的角度

时间:2011-08-29 20:50:55

标签: javascript

JavaScript问题。

以下是一个似乎有一些问题的例行程序。问题是什么?给定两点的函数应该返回水平轴和包含两个点(X1,Y1)和(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;
}

3 个答案:

答案 0 :(得分:9)

为什么不使用Math.atan2,这更方便。当两个数字都为负数时(分割时丢失哪些信息),它会自动执行,并为边缘情况返回正确的值。

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

答案 1 :(得分:1)

该函数正在计算切线的倒数。

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

但是,正如pimvdb所提到的那样,最好使用Math.atan2()

答案 2 :(得分:0)

感谢您的帮助!我确实尝试过atan2,但在某些情况下它不能正常工作。我编写了自己的函数来处理这个问题。这里是。效果很好。

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
    }