问题描述
我在这里有点生锈.
我有一个向量(camDirectionX,camDirectionY,camDirectionZ)代表我的相机视角.我的相机位置是(camX,camY,camZ).
然后,我有一个对象放置在(objectX,objectY,objectZ)
如何从相机角度计算方位角&我的物体的高度??
为简化问题,我要做的第一件事是变换坐标空间,以使相机位于(0,0,0)并笔直指向下方轴之一(因此方向为(0,0,1)).进行平移以使相机位于(0,0,0)处是微不足道的,因此我不再赘述.旋转以使相机方向为(0,0,1)有点棘手...
一种实现方法是构造相机的整个正交基础,然后将其粘贴在旋转矩阵中并应用它.相机的正交基础"是一种奇特的方式,可以说出从相机指向前方,上方和右侧的三个向量.它们都应彼此成90度角(这是正交位的含义),并且它们都应具有1的长度(这是普通位的含义).
您可以获得带有一些叉积技巧的矢量:两个矢量的叉积与两者垂直(成90度).
要获得右向向量,我们可以将相机方向向量与(0,1,0)(一个指向上的向量)进行叉积.您需要对从叉积中得到的向量进行归一化.
要获取相机的向上矢量,我们可以将相机方向矢量与刚计算出的右向矢量进行乘积运算.假设两个输入向量都已归一化,则不需要归一化.
我们现在有了相机的正交基准.如果将这些向量粘贴到3x3矩阵的行中,则会得到一个旋转矩阵,该矩阵将转换我们的坐标空间,因此摄影机将直接指向其中一个轴(该轴取决于您粘贴向量的顺序)./p>
现在很容易计算出物体的方位角和高度.
要获取方位角,只需在对象的x/z坐标上执行atan2
.
要获取高程,请将对象坐标投影到x/z平面上(只需将y坐标设置为0),然后执行以下操作:
acos(dot(normalise(object coordinates), normalise(projected coordinates)))
这将始终产生一个正角-如果对象的y坐标小于0,您可能想取消它.
所有这些的代码如下所示:
fwd = vec3(camDirectionX, camDirectionY, camDirectionZ)
cam = vec3(camX, camY, camZ)
obj = vec3(objectX, objectY, objectZ)
# if fwd is already normalised you can skip this
fwd = normalise(fwd)
# translate so the camera is at (0, 0, 0)
obj -= cam
# calculate the orthonormal basis of the camera
right = normalise(cross(fwd, (0, 1, 0)))
up = cross(right, fwd)
# rotate so the camera is pointing straight down the z axis
# (this is essentially a matrix multiplication)
obj = vec3(dot(obj, right), dot(obj, up), dot(obj, fwd))
azimuth = atan2(obj.x, obj.z)
proj = vec3(obj.x, 0, obj.z)
elevation = acos(dot(normalise(obj), normalise(proj)))
if obj.y < 0:
elevation = -elevation
需要注意的一件事是,当您的相机面向上或朝下时,原始相机矢量与(0,1,0)的叉积将返回零长度矢量.为了完全定义相机的方向,我假定它始终是笔直的",但这并不意味着它在笔直向上或向下时的任何内容,您需要另外一条规则.
I'm rusty a bit here.
I have a vector (camDirectionX, camDirectionY, camDirectionZ) that represents my camera direction of view.I have a (camX, camY, camZ) that is my camera position.
Then, I have an object placed at (objectX, objectY, objectZ)
How can I calculate, from the camera point of view, the azimut & elevation of my object ??
The first thing I would do, to simplify the problem, is transform the coordinate space so the camera is at (0, 0, 0) and pointing straight down one of the axes (so the direction is say (0, 0, 1)). Translating so the camera is at (0, 0, 0) is pretty trivial, so I won't go into that. Rotating so that the camera direction is (0, 0, 1) is a little trickier...
One way of doing it is to construct the full orthonormal basis of the camera, then stick that in a rotation matrix and apply it. The "orthonormal basis" of the camera is a fancy way of saying the three vectors that point forward, up, and right from the camera. They should all be at 90 degrees to each other (which is what the ortho bit means), and they should all be of length 1 (which is what the normal bit means).
You can get these vectors with a bit of cross-product trickery: the cross product of two vectors is perpendicular (at 90 degrees) to both.
To get the right-facing vector, we can just cross-product the camera direction vector with (0, 1, 0) (a vector pointing straight up). You'll need to normalise the vector you get out of the cross-product.
To get the up vector of the camera, we can cross product the camera direction vector with the right-facing vector we just calculated. Assuming both input vectors are normalised, this shouldn't need normalising.
We now have the orthonormal basis of the camera. If we stick these vectors into the rows of a 3x3 matrix, we get a rotation matrix that will transform our coordinate space so the camera is pointing straight down one of the axes (which one depends on the order you stick the vectors in).
It's now fairly easy to calculate the azimuth and elevation of the object.
To get the azimuth, just do an atan2
on the x/z coordinates of the object.
To get the elevation, project the object coordinates onto the x/z plane (just set the y coordinate to 0), then do:
acos(dot(normalise(object coordinates), normalise(projected coordinates)))
This will always give a positive angle -- you probably want to negate it if the object's y coordinate is less than 0.
The code for all of this will look something like:
fwd = vec3(camDirectionX, camDirectionY, camDirectionZ)
cam = vec3(camX, camY, camZ)
obj = vec3(objectX, objectY, objectZ)
# if fwd is already normalised you can skip this
fwd = normalise(fwd)
# translate so the camera is at (0, 0, 0)
obj -= cam
# calculate the orthonormal basis of the camera
right = normalise(cross(fwd, (0, 1, 0)))
up = cross(right, fwd)
# rotate so the camera is pointing straight down the z axis
# (this is essentially a matrix multiplication)
obj = vec3(dot(obj, right), dot(obj, up), dot(obj, fwd))
azimuth = atan2(obj.x, obj.z)
proj = vec3(obj.x, 0, obj.z)
elevation = acos(dot(normalise(obj), normalise(proj)))
if obj.y < 0:
elevation = -elevation
One thing to watch out for is that the cross-product of your original camera vector with (0, 1, 0) will return a zero-length vector when your camera is facing straight up or straight down. To fully define the orientation of the camera, I've assumed that it's always "straight", but that doesn't mean anything when it's facing straight up or down -- you need another rule.
这篇关于如何计算方位角相对于3D摄影机视角的仰角...?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!