如下所示,假设存在指向对象的虚拟相机,并且两者都由相对于全局坐标系的方向和位置定义。在图中,黑色表示GCS,蓝色表示LCS。
在这种情况下,某些物体(例如屏幕或LED)具有视角。例如,如果与观察者的角度在±70°
范围内,则只能看到它们为了解决这个问题,到目前为止,我采取了以下伪代码演示的步骤。在适用的情况下,我们使用右手坐标系统,使用按ZYX顺序应用的外部旋转。
LEDToWorldTransform = LED.Transform;
CameraToWorldTransform = Camera.Transform;
WorldToCameraTransform = CameraToWorldTransform.Inverse;
CameraToLEDTransform = WorldToCameraTransform * LEDToWorldTransform;
据我所知,CameraToLEDTransform现在应该包含LED相对于相机坐标系的平移和旋转。出于可视化目的:
现在这就是我卡住的地方,看着CameraToLEDTransform
的euler组件我认为我们可以得出结论,相对于相机坐标系的旋转Z分量不会影响LED的观察。我尝试了以下哪些我不确定是否正确。请注意,在第三步中,我试图翻转其中一个Z轴的方向,使它们指向相同的方向
R_Z, R_Y, R_X = CameraToLEDTransform.Rotation.Eulers
CameraToLEDTransform.Rotation.Eulers = 0, R_Y, R_X
CameraToLEDTransform.Rotation *= Rotation.AngleAxis[180deg,X]
Angle, Axis = CameraToLEDTransform.Rotation.AngleAxis
这给出了一种看起来正确的答案,但是我怀疑某些事情可能是错误的,因为遵循我的逻辑我也应该能够用以下内容替换第三步:
CameraToLEDTransform.Rotation *= Rotation.AngleAxis[180deg,Y]
然而,情况并非如此,我得到了一个不同的(当然是错误的)答案。这种方法可能完全错误,我当然不明白为什么在X周围旋转180与在这种情况下围绕Y旋转180不同。也许另一种方法是使用Dot产品来计算角度,但我认为这仅适用于两个矢量而不是两个旋转。似乎根据两个物体的方向投射两个新的矢量将是一个非常接近的方法...
答案 0 :(得分:2)
使用点积不是一个圆的方法,它是正确的方法。您必须使用相机的视图方向矢量和法线(即从观察者到所讨论的LED /物体的矢量)之间的点积来获得所需角度的余弦。如果对象是像屏幕一样的 surface ,则可能需要使用曲面的法线。
[
{
"
i
d
"
:
"
0
"
,
"
s
r
s
"
:
"
M
c
D
o
n
a
l
d
s
S
u
p
e
r
S
m
a
s
h
,
2
0
1
6
-
1
7
"
,
"
m
c
h
d
e
s
在检查角度是否在所需范围内时,我们可以使用// normalized returns a unit vector
Vector3 normal = (led.position - observer.position).Normalized();
Vector3 lookDirection = observer.lookDirection; // Should be a unit vector
float cosAngle = Vector3.Dot(normal, lookDirection);
函数的以下属性来避免cos
调用:
如果
acos
,-angle <= theta <= angle
。 (试试吧!)
您的支票如下:
cos(theta) >= cos(angle)