从点到角的三维坐标 [英] 3d coordinate from point and angles
问题描述
我在一个简单的OpenGL世界上工作--到目前为止,我已经有一堆随机放置的立方体,四处缩放非常有趣。不过,我已经准备好继续前进了。我很想在我的相机前丢掉积木,但我在3D角度上遇到了麻烦。我习惯了2D的东西,在那里找到终点我们只需做如下的事情:
endy = y + (sin(theta)*power);
endx = x + (cos(theta)*power);
然而,当我添加第三个维度时,我不确定该做什么!在我看来,第二维平面的功率将由z轴的cos(Theta)*次方决定,但我并不肯定。如果这是正确的,在我看来,我会这样做:
endz = z + (sin(xtheta)*power);
power2 = cos(xtheta) * power;
endx = x + (cos(ytheta) * power2);
endy = y + (sin(ytheta) * power2);
(其中x theta为上/下theta,y=左/右theta)
我是不是接近了正确的轨道?如何找到给定当前点和两个角度的终点?
推荐答案
使用欧拉角在3D环境中不能很好地工作,有几个问题和角落情况下它们根本不能工作。实际上,你甚至不需要使用它们。
您应该做的是利用这样一个事实,即变换矩阵不是其他任何东西,然后以可理解的形式写下坐标系基础。这样你就有了模型视图矩阵MV。这包括模型空间转换,然后是视图转换(列主要矩阵从右到左相乘):MV = V * M
所以我们想知道的是,"相机"以何种方式存在于这个世界之中。这是由逆视图矩阵V^-1
提供给您的。当然,您可以使用Gauss Jordan方法来反转视图矩阵,但大多数情况下,您的视图矩阵将由一个添加了平移向量列P的3x3旋转矩阵组成。
R P
0 1
回想一下
(M * N)^-1 = N^-1 * M^-1
和
(M * N)^T = M^T * N^T
因此,似乎在换位和倒置之间有某种关系。并不是所有的转置矩阵都是它们的逆矩阵,但是有一些矩阵的转置矩阵是它的逆矩阵。也就是说,它是所谓的正交化矩阵。旋转是正交化的。因此
R^-1 = R^T
整齐!这使我们可以通过以下方法找到视图矩阵的逆(我建议您尝试将其作为练习进行证明):
V = / R P
0 1 /
V^-1 = / R^T -P
0 1 /
那么,这如何帮助我们将新对象放置在场景中远离相机的位置?V是从世界空间到相机空间的转换,所以V^-1是从相机到世界空间的转换。因此,给定相机空间中的一个点,您可以将其转换回世界空间。假设您想要将某物放置在距离d
的视图中心。在相机空间,这将是点(0, 0, -d, 1)
。将其乘以V^-1:
V^-1 * (0, 0, -d, 1) = (R^T)_z * d - P
这正是您想要的。在您的OpenGL程序中,您的某个地方有您的视图矩阵V,可能还没有正确命名,但不管怎样,它就在那里。假设您使用旧的OpenGL-1和GLU的GluLookAt:
void display(void)
{
/* setup viewport, clear, set projection, etc. */
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(...);
/* the modelview matrix now holds the View transform */
此时,我们可以提取模型视图矩阵
GLfloat view[16];
glGetFloatv(GL_MODELVIEW_MATRIX, view);
现在view
按列主序排列。如果我们直接使用它,我们可以直接处理列。但请记住,转置与旋转相反,所以我们实际上需要第三行向量。因此,假设您保留了view
,以便在事件处理程序(外部显示)中执行以下操作:
GLfloat z_row[3];
z_row[0] = view[2];
z_row[1] = view[6];
z_row[2] = view[10];
我们想要这个职位
GLfloat * const p_column = &view[12];
现在我们可以计算距离d
的新对象位置:
GLfloat new_object_pos[3] = {
z_row[0]*d - p_column[0],
z_row[1]*d - p_column[1],
z_row[2]*d - p_column[2],
};
给你。正如你所看到的,你不需要研究角度或三角,它只是直线型代数。
这篇关于从点到角的三维坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!