2011-08-29 331 views
4

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

...有什么问题?它给出的错误信息?你执行它时得到的角度? – woliveirajr

回答

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

该函数计算切线的倒数。

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

但是最好使用Math.atan2(),因为pimvdb已经提到。

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 
    }