如何获得面向的方向和 3D 空间中的点之间的角度

Posted

技术标签:

【中文标题】如何获得面向的方向和 3D 空间中的点之间的角度【英文标题】:How to get an angle between a direction faced and a point in 3D space 【发布时间】:2013-03-28 12:55:05 【问题描述】:

我掌握的信息是玩家视线的垂直角度、到问题点的水平角度、到该点的距离以及该点的垂直高度。

如果玩家没有向上或向下看(垂直角度),我已经想出了如何使用以下方法获取角度。

float GetVisionAngle(float angleHoriz, float angleVert, float distance, float height)

double A = Math.Cos(angleHoriz * (Math.PI / 180)) * distance);
double hypotenuse = Math.Sqrt(distance * distance + height * height);
return (float)(Math.Acos(A / hypotenuse) * (180 / Math.PI));

如果玩家的视线方向被垂直角度(向上或向下)修改,我无法弄清楚如何获得该角度。这几天我一直在脑子里想这件事,我想不出办法。

我使用它的目的是生成视锥截止。当检查对象的可见性时,我必须处理的信息是对象与玩家的角度、到该对象的距离及其高度。此初始范围检查将返回玩家视线方向的角度,并确定对象是否可见。

这是使用@HABO提供的解决方案进行调试的代码截图 不幸的是,它总是导致 NaN 错误。

在使用它们之前将角度转换为弧度似乎可以解决很多数值错误。我不明白最后将前面的数字转换为最终角度的公式。

【问题讨论】:

【参考方案1】:
aH = Angle in the horizontal plane between the line of sight (LOS) and the object.  (angleHoriz)

aV = Angle in the vertical plane of the LOS.  (angleVert)

d = Distance to the object in the horizontal plane.  (distance)

h = Height of the object above the horizontal plane.  (height)

dO = Distance from the origin to the object.
   = sqrt( d * d + h * h )

oH = Horizontal offset from the LOS to the object at the base of the wall.
   = sin( aH ) * d

dH = Horizontal distance from the origin to the wall.
   = cos( aH ) * d

hLOS = Height at which the LOS intersects the wall.
     = tan( aV ) * dH

dLOS = Distance from the observer to the LOS at the wall.
     = sqrt( dH * dH + hLOS * hLOS )

dW = Distance along the wall between the line of sight and the object.
   = sqrt( oH * oH + ( h - hLOS ) * ( h - hLOS ) )

answer = acos( ( dLOS * dLOS + dO * dO - dW * dW ) / ( 2 * dLOS * dO ) )

【讨论】:

这非常简洁明了,但出于某种奇怪的原因,我插入的每一组变量都返回 Not a Number。我将编写一个示例集向您展示,希望您能看到错误发生的位置。 aH = 45; aV = 10; d = 141.421356; h = 172.8; dO = 223.29317285682123; oH = 120.33593043597216; dH = 74.291748100900179; hLOS = 48.167859272081671; dLOS = 88.540422987145647; dW = 173.2452233598635;答案 = NaN;问题可能是 C# 使用弧度而不是度数? @Steve - 我试图逐步研究几何图形以展示如何获得答案。 (使用极坐标也可以,尽管我不认为 .NET 支持 3D 极坐标。)使用弧度表示角度或根据需要从度数或梯度转换是明智的。请注意,当我学习几何时,那个毕达哥拉斯的人非常先进。我很可能在某个地方搞砸了。 我做了一些测试,数学函数似乎使用的是弧度而不是度数。将角度转换为弧度似乎可以在最终答案之前修复很多奇怪的数字。您能否解释一下最终答案是如何得出的?我跟进到那一点,但最后我有点迷失了。我将包含一组更新的简单数字供您在 OP 中查看。 @Steve - 最后的然后奇迹发生步骤从Wikipedia中解放出来。 Mea culpa:我已经编辑了最后一步以包含一对额外的括号。我的一个愚蠢的运算符优先级错误。这应该为您的样本值提供大约 40.5 度的结果。

以上是关于如何获得面向的方向和 3D 空间中的点之间的角度的主要内容,如果未能解决你的问题,请参考以下文章

VTKvtk actor空间变换后的点映射与向量映射

JavaScript如何获得两点之间顺时针旋转的角度

来自 3 个视点的 3 个图像上的三个点如何获得其在 3d 空间中的坐标?

三角测量在3D空间的任意平面上的点集

Unity3D在特定轴上的矢量/方向之间的角度

将纬度和经度转换为 3D 空间中的点