Reputation: 55
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;
}
Upvotes: 4
Views: 4975
Reputation: 55
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
}
Upvotes: 0
Reputation: 154818
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
Upvotes: 9
Reputation: 8628
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.
Upvotes: 1