如何计算两点之间的角度?

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/

如果有人知道我如何修复角度函数以提供正确的结果,请帮助!

编辑:

这是问题的图片:

https://i.stack.imgur.com/EpLXC.jpg

Yun*_*hai 5

根据您提供的照片样本,为了获得当前功能所需的角度Math.atan(),您需要reverse首先然后rotate the angle by 90 degrees couter clockwise

\n\n
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}\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者简单地+ 90 度到这条线而不deltaX改变deltaY

\n\n

let degrees = (radians * 180) / Math.PI + 90; // rotate

\n\n

注意:我还没有测试所有可能的边缘情况

\n\n

\r\n
\r\n
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}\n
Run Code Online (Sandbox Code Playgroud)\r\n
const 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
\r\n
\r\n

\n