来自点和角度的 3d 坐标
我正在研究一个简单的 OpenGL 世界 - 到目前为止,我已经随机放置了一堆立方体,缩放非常有趣。不过我已经准备好继续前进了。我想在相机前放下方块,但我在 3D 角度方面遇到了麻烦。我习惯了二维的东西,在哪里找到终点,我们只需做一些类似的事情:
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)
我在这里是否接近正确的轨道?给定当前点和两个角度,如何找到终点?
I'm working on a simple OpenGL world- and so far I've got a bunch of cubes randomly placed about and it's pretty fun to go zooming about. However I'm ready to move on. I would like to drop blocks in front of my camera, but I'm having trouble with the 3d angles. I'm used to 2d stuff where to find an end point we simply do something along the lines of:
endy = y + (sin(theta)*power);
endx = x + (cos(theta)*power);
However when I add the third dimension I'm not sure what to do! It seems to me that the power of the second dimensional plane would be determined by the z axis's cos(theta)*power, but I'm not positive. If that is correct, it seems to me I'd do something like this:
endz = z + (sin(xtheta)*power);
power2 = cos(xtheta) * power;
endx = x + (cos(ytheta) * power2);
endy = y + (sin(ytheta) * power2);
(where x theta is the up/down theta and y = left/right theta)
Am I even close to the right track here? How do I find an end point given a current point and an two angles?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用欧拉角在 3D 环境中效果不太好,存在一些问题和极端情况,它们根本不起作用。实际上您甚至不必使用它们。
您应该做的是利用变换矩阵这一事实,然后以可理解的形式写下坐标系基础。这样你就有了模型视图矩阵 MV。这包括模型空间变换,然后是视图变换(列主矩阵从右到左相乘):
所以我们想知道的是,“相机”在世界中的位置。这是由逆视图矩阵
V^-1
给出的。当然,您可以使用 Gauss Jordan 方法反转视图矩阵,但大多数时候您的视图矩阵将由 3×3 旋转矩阵组成,并添加平移向量列 P。回想一下
,
换位和倒置之间似乎也存在某种关系。并非所有转置矩阵都是其逆矩阵,但有一些矩阵的转置矩阵是其逆矩阵。即它是所谓的正交矩阵。旋转是正交的。太
整洁了!这使我们能够通过以下方式找到视图矩阵的逆(我建议您尝试将其作为练习进行证明):
那么这如何帮助我们将新对象放置在距相机一定距离的场景中?嗯,V是从世界空间到相机空间的变换,所以V^-1从相机到世界空间的变换。因此,给定相机空间中的一个点,您可以将其转换回世界空间。假设您想在视图中心放置一些距离
d
的东西。在相机空间中,该点为(0, 0, -d, 1)
。将其乘以 V^-1:这正是您想要的。在你的 OpenGL 程序中,你的某个地方有你的视图矩阵 V,可能还没有正确命名,但无论如何它就在那里。假设您使用旧的 OpenGL-1 和 GLU 的 gluLookAt:
此时我们可以提取模型视图矩阵
现在
view
按列主要顺序排列。如果我们直接使用它,我们可以直接对列进行寻址。但请记住,转置是旋转的逆运算,因此我们实际上需要第三行向量。因此,我们假设您保持view
不变,以便在事件处理程序(显示屏外)中您可以执行以下操作:我们想要位置
现在我们可以计算距离
d 处的新对象位置
:你来了。正如您所看到的,在任何地方您都不需要使用角度或三角学,它只是直线代数。
Working with euler angles doesn't work so well in 3D environments, there are several issues and corner cases in which they simply don't work. And you actually don't even have to use them.
What you should do, is exploit the fact, that transformation matrixes are nothing else, then coordinate system bases written down in a comprehensible form. So you have your modelview matrix MV. This consists of a model space transformation, followed by a view transformation (column major matrices multiply right to left):
So what we want to know is, in which way the "camera" lies within the world. That is given to you by the inverse view matrix
V^-1
. You can of course invert the view matrix using Gauss Jordan method, but most of the time your view matrix will consist of a 3×3 rotation matrix with a translation vector column P added.Recall that
and also
so it seems there is some kind of relationship between transposition and inversion. Not all transposed matrices are their inverse, but there are some, where the transpose of a matrix is its inverse. Namely it are the so called orthonormal matrices. Rotations are orthonormal. So
neat! This allows us to find the inverse of the view matrix by the following (I suggest you try to proof it as an exersice):
So how does this help us to place a new object in the scene at a distance from the camera? Well, V is the transformation from world space into camera space, so V^-1 transforms from camera to world space. So given a point in camera space you can transform it back to world space. Say you wanted to place something at the center of the view in distance
d
. In camera space that would be the point(0, 0, -d, 1)
. Multiply that with V^-1:Which is exactly what you want. In your OpenGL program you somewhere have your view matrix V, probably not properly named yet, but anyway it is there. Say you use old OpenGL-1 and GLU's gluLookAt:
At this point we can extract the modelview matrix
Now
view
is in column major order. If we were to use it directly we could directly address the columns. But remember that transpose is inverse of a rotation, so we actually want the 3rd row vector. So let's assume you keepview
around, so that in your event handler (outside display) you can do the following:And we want the position
Now we can calculate the new objects position at distance
d
:There you are. As you can see, nowhere you had to work with angles or trigonometry, it's just straight linear algebra.
好吧,我很接近,经过一些测试,我找到了正确的实现公式,它看起来像这样:
这需要我的相机的位置和旋转角度并得到相应的点。就像一个魅力=]
Well I was close, after some testing, I found the correct formula for my implementation, it looks like this:
This takes my camera's position and rotational angles and get's the corresponding points. Works like a charm =]