I am attempting to create a 2d tile based game in Javascript, and I need to be able to calculate the angle between two points. I am using the atan2 function to find the angle between two points like so:
function getAngleDegrees(fromX, fromY, toX, toY, force360 = true) {
let deltaX = toX - fromX;
let deltaY = toY - fromY;
let radians = Math.atan2(deltaY, deltaX);
let degrees = (radians * 180) / Math.PI;
if (force360) {
while (degrees >= 360) degrees -= 360;
while (degrees < 0) degrees += 360;
}
return degrees;
}
However, this isn't providing me with the correct result. I have checked the code for logic or math errors and can't find any. No matter what points I input to this function the result will be off by many degrees.
I have created a JS fiddle to visualize the problem:
https://jsfiddle.net/fa6o7wdy/40/
If anyone knows how I can fix my angle function to provide the correct result please help!
Edit:
Here is a picture of the problem:
https://i.sstatic.net/EpLXC.jpg
Based on the photo sample you provide, for getting the desired angle you want with current Math.atan() function, you want to reverse first and then rotate the angle by 90 degrees couter clockwise
function getAngleDegrees(fromX,fromY,toX,toY,force360 = true) {
let deltaX = fromX-toX;
let deltaY = fromY-toY; // reverse
let radians = Math.atan2(deltaY, deltaX)
let degrees = (radians * 180) / Math.PI - 90; // rotate
if (force360) {
while (degrees >= 360) degrees -= 360;
while (degrees < 0) degrees += 360;
}
console.log('angle to degree:',{deltaX,deltaY,radians,degrees})
return degrees;
}
or simply + 90 degrees to this line without changing deltaX and deltaY
let degrees = (radians * 180) / Math.PI + 90; // rotate
Note: I haven't test out all possible edge cases
const inBlk = document.createElement('i')
, getXY = (p,xy) => Number(p.split('-')[xy==='x'?0:1])
;
for(let i=0;i<100;i++) // build Grid
{
let nI = inBlk.cloneNode()
, u1 = i%10
;
nI.textContent = u1+'-'+(i-u1)/10
grid.appendChild(nI)
}
let points = [ {x:0, y:0, old:null}, {x:0, y:0, old:null}]
, pN = 0
;
grid.onclick=e=>
{
if (!e.target.matches('i')) return
let elm = e.target.textContent
points[pN].x = getXY(elm, 'x')
points[pN].y = getXY(elm, 'y')
if (points[pN].old ) points[pN].old.classList.remove('color_0', 'color_1')
points[pN].old = e.target
points[pN].old.classList.add(`color_${pN}` )
pN = ++pN %2
if (pN==0) angle.textContent = ` angle: ${getAngleDegrees(points[0],points[1])}°`
}
function getAngleDegrees( from, to, force360 =true)
{
let deltaX = from.x - to.x
, deltaY = from.y - to.y // reverse
, radians = Math.atan2(deltaY, deltaX)
, degrees = (radians * 180) / Math.PI - 90 // rotate
;
if (force360)
{
while (degrees >= 360) degrees -= 360;
while (degrees < 0) degrees += 360;
}
return degrees.toFixed(2)
}
:root { --sz-hw: 26px; }
#grid {
font-family: 'Courier New', Courier, monospace;
font-size : 10px;
margin : calc( var(--sz-hw) /2);
}
#grid i {
display : block;
float : left;
width : var(--sz-hw);
height : var(--sz-hw);
border : 1px solid grey;
text-align : center;
margin : 2px;
line-height: var(--sz-hw);
cursor : pointer;
}
#grid i:nth-child(10n-9) {clear: both; }
.color_0 { background-color: lightcoral; }
.color_1 { background-color: lightgreen; }
#angle { padding: calc( var(--sz-hw) /2) 0 0 calc( var(--sz-hw) *13.4); }
<p id="grid"></p>
<h4 id="angle">angle: ?</h4>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With