I would like to get an angle in terms of 360 degrees... for my game, I need to know which direction the player is heading in...
The code here gets the proper angles, but only in terms of 90 degree increments: (meaning, when I click in upper left quadrant, I get angle from 0 to 90 degrees... bottom left is 0 to -90 degrees, etc...)
var dY = this.pos.y-e.gameY; //opposite
var dX = this.pos.x-e.gameX; //adjacent
var dist = Math.sqrt((dY*dY)+(dX*dX)); //hypotenuse
var sin = dY/dist; //opposite over hypotenuse
var radians = Math.asin(sin);
var degrees = radians*(180/Math.PI); //convert from radians to degrees
this.calculatedAngle = degrees;
How can I get it in terms of 360 degrees?
Here is another example: The top two represent the issue... when I click in the upper/lower left quadrant, it keeps drawing a right triangle from the x axis...
I need it to be like the lower 2 pictures, where it keeps drawing the angle around:
You can do this directly from the coordinates, without computing extra information like the hypotenuse, by using the atan2
function, which was designed in the early days of FORTRAN for situations exactly like yours.
Note two important things:
atan2
function has been created to automatically handle all but one case of the many possible cases, and(-PI, PI]
.The case where both coordinates are (0, 0) is left undefined (all angles are equivalent when the magnitude of a vector is zero), so I'm arbitrarily setting the angle to zero degrees in that case. And in order to obtain the desired range, some simple logic and addition is needed.
var Vx = this.pos.x - e.gameX;
var Vy = this.pos.y - e.gameY;
var radians;
if (Vx || Vy) {
radians = Math.atan2(Vy, Vx);
} else {
radians = 0;
}
if (radians < 0) {
radians += 2*Math.PI;
}
var degrees = radians * 180 / Math.PI;
this.calculatedAngle = degrees;
The result will be an angle defined for all cases and within the range [0, 360°), as desired.
function showDegrees(e, svg) {
var rectangle = svg.getBoundingClientRect();
var targetX = (rectangle.left + rectangle.right)/2;
var targetY = (rectangle.top + rectangle.bottom)/2;
var Vx = Math.round(e.clientX - targetX);
var Vy = Math.round(targetY - e.clientY);
var radians = Math.atan2(Vy, Vx);
if (radians < 0) radians += 2*Math.PI;
var degrees = Math.round(radians*180/Math.PI);
var textBox = document.getElementById('showdegrees');
textBox.innerHTML = degrees + '°' + ' (' + Vx + ', ' + Vy + ')';
textBox.setAttribute('x', Math.round(100 + Vx));
textBox.setAttribute('y', Math.round(100 - Vy));
}
<svg width="200" height="200" viewBox="0 0 200 200" onmousemove="showDegrees(evt, this)">
<text x="0" y="0" fill="red" style="font-size: 12px" id="showdegrees">Info</text>
<line x1="100" y1="0" x2="100" y2="200" style="stroke: black; stroke-width: 1" />
<line x1="0" y1="100" x2="200" y2="100" style="stroke: black; stroke-width: 1" />
</svg>