好的,这是一个非常具体的问题,与我在OpenGL中的相机变换有关。当视图打开时,旋转点位于原点附近 - 当您平移相机时,它首先进行平移,然后旋转以保持旋转点围绕原点。
好吧,我想让旋转点从原点变为你点击的六边形瓷砖,而不会让相机位置发生变化。这看起来很模糊,所以我附上了一些图片来说明。
我不能包含图片,因为我的代表在这里不够高,但这里是flickr上照片的链接
现在,当我点击新图块来更改旋转点时,相机会移动以将该图块保持在屏幕的中心。我会发布一个链接显示,但只有两个链接只有足够的代表 - 所以我会发布一个链接到我希望如何改变旋转点的图片(当旋转点改变时相机不移动)
现在好了一些代码 - 这里是获取相机变换矩阵的代码
NSMatrix4Df rotateTransform = NSMatrix4Df::getRotationMatrix(-orientation.x,-orientation.y,-orientation.z);
NSMatrix4Df rotationTranslationTransform = NSMatrix4Df::getTranslationMatrix(rotationPoint.x,rotationPoint.y,rotationPoint.z);
NSMatrix4Df cameraTranslateTransform = NSMatrix4Df::getTranslationMatrix(position.x,position.y,position.z);
return cameraTranslateTransform * rotateTransform * rotateTransform;
其中orientation,position和rotationPoint都在世界空间中。这是实际矩阵变换的代码。
NSMatrix4Df NSMatrix4Df::getRotationMatrix(float xAxisAng, float yAxisAng, float zAxisAng)
{
float xRad = DegreesToRadians(xAxisAng);
float yRad = DegreesToRadians(yAxisAng);
float zRad = DegreesToRadians(zAxisAng);
NSMatrix4Df xRotMat;
NSMatrix4Df yRotMat;
NSMatrix4Df zRotMat;
xRotMat.value(1,1) = cosf(xRad); xRotMat.value(1,2) = -sinf(xRad);
xRotMat.value(2,1) = sinf(xRad); xRotMat.value(2,2) = cosf(xRad);
yRotMat.value(0,0) = cosf(yRad); yRotMat.value(0,2) = -sinf(yRad);
yRotMat.value(2,0) = sinf(yRad); yRotMat.value(2,2) = cosf(yRad);
zRotMat.value(0,0) = cosf(zRad); zRotMat.value(0,1) = -sinf(zRad);
zRotMat.value(1,0) = sinf(zRad); zRotMat.value(1,1) = cosf(zRad);
return zRotMat * yRotMat * xRotMat;
}
NSMatrix4Df NSMatrix4Df::getTranslationMatrix(float xMove, float yMove, float zMove)
{
NSMatrix4Df identity;
// set the fourth column of the matrix to the translation amount
// the rest of the matrix is the identity matrix
identity.setColumn(NSVec4Df(xMove,yMove,zMove,1),3);
return identity;
}
NSMatrix4Df创建一个二维数组,表示填充了单位矩阵的4x4矩阵([4] [4])。代码就在这里。
NSMatrix4Df::NSMatrix4Df():rows(MATDIM4D),
columns(MATDIM4D)
{
data[0][0] = 1; data[0][1] = 0; data[0][2] = 0; data[0][3] = 0;
data[1][0] = 0; data[1][1] = 1; data[1][2] = 0; data[1][3] = 0;
data[2][0] = 0; data[2][1] = 0; data[2][2] = 1; data[2][3] = 0;
data[3][0] = 0; data[3][1] = 0; data[3][2] = 0; data[3][3] = 1;
}
基本上我的问题是这个 - 有人知道如何在移动旋转点后平移相机的位置,以便在旋转点移动时相机保持在同一位置。我尝试在旋转点转换之后添加一个翻译,如此...
NSMatrix4Df rotateTransform = NSMatrix4Df::getRotationMatrix(-orientation.x,-orientation.y,-orientation.z);
NSMatrix4Df rotationTranslationTransform = NSMatrix4Df::getTranslationMatrix(rotationPoint.x,rotationPoint.y,rotationPoint.z);
NSMatrix4Df cameraTranslateTransform = NSMatrix4Df::getTranslationMatrix(**position.x - rotationPoint.x,position.y - rotationPoint.y,position.z - rotationPoint.z**);
return cameraTranslateTransform * rotateTransform * rotateTransform;
除了在更改旋转点之前完全旋转相机之外,这是有效的,我无法弄清楚原因。在这种情况下(当在改变旋转点之前旋转摄像机时)摄像机将以受旋转量影响的方式平移。因此,例如,如果围绕x轴旋转45度,则将导致相机在x方向上变换额外的量。我无法弄清楚原因。
我知道将相机旋转到原点以外的点进行翻译*旋转* - 翻转这是我在最后一种情况下的情况,但如果旋转相机则最终平移不正确。我认为我的翻译或轮换代码肯定有问题,但我不知道是什么。
我知道这是一个复杂的问题,如果有人有任何见解我会很感激帮助。谢谢你的时间。
答案 0 :(得分:1)
您正在遇到矩阵乘法的基本属性。如果你有实数4 * 5 == 5 * 4。然而,对于矩阵来说并非如此。
我有点醉,写这个答案,所以我可能会弄错,因为它恰好与自然相反:最右边的变换首先发生,左边的变换发生。
测试此功能的一种简单方法是左右尝试相机矩阵。其中一个会做你想要的:)通常将右侧的矩阵乘法视为对不同空间的变换非常有帮助。在3D中通常是MODEL * CAMERA * PROJECTION。现在你想改变CAMERA。你想要在它之前或之后进行变换。假设您通过鼠标输入INPUT的矩阵进行更改。然后你可以做INPUT * CAMERA或CAMERA * INPUT。在第一种情况下,您的参考框架是没有相机的世界,在第二种情况下,它是相机看到的世界。
您正在尝试执行与应用和撤消翻译类似的操作,但这还不够。
我希望这会有所帮助。随意跟进。但也读了矩阵数学。这是一个陡峭的学习曲线,但非常值得,从你的问题判断你非常接近:)