首页 > 解决方案 > 如何计算两点之间的角度?

问题描述

我正在尝试用 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;
  }

但是,这并没有为我提供正确的结果。我检查了代码中的逻辑或数学错误,但找不到任何错误。无论我向这个函数输入什么点,结果都会偏离很多程度。

我创建了一个 JS fiddle 来可视化问题:

https://jsfiddle.net/fa6o7wdy/40/

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

编辑:

这是问题的图片:

https://imgur.com/a/OXDCOux

标签: javascripthtmlmathgeometry

解决方案


根据您提供的照片样本,为了使用当前Math.atan()功能获得所需的角度,您reverse首先要然后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;
}

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

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

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

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>


推荐阅读