Dan*_*nby 3 html javascript math geometry
我正在尝试用 JavaScript 创建一个基于 2d 图块的游戏,并且我需要能够计算两点之间的角度。我正在使用 atan2 函数来查找两点之间的角度,如下所示:
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;
}
Run Code Online (Sandbox Code Playgroud)
但是,这并没有为我提供正确的结果。我检查了代码是否存在逻辑或数学错误,但找不到任何错误。无论我向该函数输入什么点,结果都会有很多偏差。
我创建了一个 JS 小提琴来可视化问题:
https://jsfiddle.net/fa6o7wdy/40/
如果有人知道我如何修复角度函数以提供正确的结果,请帮助!
编辑:
这是问题的图片:
根据您提供的照片样本,为了获得当前功能所需的角度Math.atan(),您需要reverse首先然后rotate the angle by 90 degrees couter clockwise
function getAngleDegrees(fromX,fromY,toX,toY,force360 = true) {\n let deltaX = fromX-toX; \n let deltaY = fromY-toY; // reverse\n let radians = Math.atan2(deltaY, deltaX)\n let degrees = (radians * 180) / Math.PI - 90; // rotate\n if (force360) {\n while (degrees >= 360) degrees -= 360;\n while (degrees < 0) degrees += 360;\n }\n console.log(\'angle to degree:\',{deltaX,deltaY,radians,degrees})\n return degrees;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n或者简单地+ 90 度到这条线而不deltaX改变deltaY
let degrees = (radians * 180) / Math.PI + 90; // rotate
注意:我还没有测试所有可能的边缘情况
\n\nfunction getAngleDegrees(fromX,fromY,toX,toY,force360 = true) {\n let deltaX = fromX-toX; \n let deltaY = fromY-toY; // reverse\n let radians = Math.atan2(deltaY, deltaX)\n let degrees = (radians * 180) / Math.PI - 90; // rotate\n if (force360) {\n while (degrees >= 360) degrees -= 360;\n while (degrees < 0) degrees += 360;\n }\n console.log(\'angle to degree:\',{deltaX,deltaY,radians,degrees})\n return degrees;\n}\nRun Code Online (Sandbox Code Playgroud)\r\nconst inBlk = document.createElement(\'i\')\r\n , getXY = (p,xy) => Number(p.split(\'-\')[xy===\'x\'?0:1])\r\n ; \r\nfor(let i=0;i<100;i++) // build Grid\r\n {\r\n let nI = inBlk.cloneNode()\r\n , u1 = i%10\r\n ;\r\n nI.textContent = u1+\'-\'+(i-u1)/10\r\n grid.appendChild(nI)\r\n }\r\nlet points = [ {x:0, y:0, old:null}, {x:0, y:0, old:null}]\r\n , pN = 0\r\n ;\r\ngrid.onclick=e=>\r\n {\r\n if (!e.target.matches(\'i\')) return\r\n\r\n let elm = e.target.textContent\r\n points[pN].x = getXY(elm, \'x\')\r\n points[pN].y = getXY(elm, \'y\')\r\n\r\n if (points[pN].old ) points[pN].old.classList.remove(\'color_0\', \'color_1\')\r\n\r\n points[pN].old = e.target\r\n points[pN].old.classList.add(`color_${pN}` )\r\n\r\n pN = ++pN %2\r\n if (pN==0) angle.textContent = ` angle: ${getAngleDegrees(points[0],points[1])}\xc2\xb0`\r\n }\r\n\r\nfunction getAngleDegrees( from, to, force360 =true)\r\n {\r\n let deltaX = from.x - to.x \r\n , deltaY = from.y - to.y // reverse\r\n , radians = Math.atan2(deltaY, deltaX)\r\n , degrees = (radians * 180) / Math.PI - 90 // rotate\r\n ;\r\n if (force360)\r\n {\r\n while (degrees >= 360) degrees -= 360;\r\n while (degrees < 0) degrees += 360;\r\n }\r\n return degrees.toFixed(2)\r\n }Run Code Online (Sandbox Code Playgroud)\r\n:root { --sz-hw: 26px; }\r\n#grid { \r\n font-family: \'Courier New\', Courier, monospace;\r\n font-size : 10px;\r\n margin : calc( var(--sz-hw) /2);\r\n } \r\n#grid i {\r\n display : block;\r\n float : left;\r\n width : var(--sz-hw);\r\n height : var(--sz-hw);\r\n border : 1px solid grey;\r\n text-align : center;\r\n margin : 2px;\r\n line-height: var(--sz-hw);\r\n cursor : pointer;\r\n }\r\n#grid i:nth-child(10n-9) {clear: both; }\r\n.color_0 { background-color: lightcoral; }\r\n.color_1 { background-color: lightgreen; }\r\n#angle { padding: calc( var(--sz-hw) /2) 0 0 calc( var(--sz-hw) *13.4); }Run Code Online (Sandbox Code Playgroud)\r\n