javascript - 如何计算两点之间的角度?
问题描述
我正在尝试用 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/
如果有人知道我如何修复我的角度函数以提供正确的结果,请帮助!
编辑:
这是问题的图片:
解决方案
根据您提供的照片样本,为了使用当前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 度到这条线而不改变deltaX
和deltaY
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>
推荐阅读
- json - 如何使用结构构建以下 JSON 对象
- javascript - Chrome 扩展中的“未捕获的语法错误:参数列表后缺少)”
- c++ - 关于 Ipopt 中的 Hessian 检查器,我缺少什么?
- ios - 制作 App Store 应用的自定义版本
- eclipse - 最近的 Eclipse 更新可能导致它停止运行
- r - 名称文档中的 z <- "names<-"(z, "[<-"(names(z), 3, "c2")) 行是如何读取的?
- javascript - && 被用作 if 语句?
- python - 检查用户是否在语音频道 discord.py
- javascript - 第二次单击时带有箭头的水平滚动跳过滚动位置
- javascript - 一个简单的实时人员计数器示例