在原点以外的旋转点周围翻译相机

时间:2013-03-24 10:18:21

标签: opengl matrix camera rotation transform

好的,这是一个非常具体的问题,与我在OpenGL中的相机变换有关。当视图打开时,旋转点位于原点附近 - 当您平移相机时,它首先进行平移,然后旋转以保持旋转点围绕原点。

好吧,我想让旋转点从原点变为你点击的六边形瓷砖,而不会让相机位置发生变化。这看起来很模糊,所以我附上了一些图片来说明。

我不能包含图片,因为我的代表在这里不够高,但这里是flickr上照片的链接

When view first opens

现在,当我点击新图块来更改旋转点时,相机会移动以将该图块保持在屏幕的中心。我会发布一个链接显示,但只有两个链接只有足够的代表 - 所以我会发布一个链接到我希望如何改变旋转点的图片(当旋转点改变时相机不移动)

How I want it to happen

现在好了一些代码 - 这里是获取相机变换矩阵的代码

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方向上变换额外的量。我无法弄清楚原因。

我知道将相机旋转到原点以外的点进行翻译*旋转* - 翻转这是我在最后一种情况下的情况,但如果旋转相机则最终平移不正确。我认为我的翻译或轮换代码肯定有问题,但我不知道是什么。

我知道这是一个复杂的问题,如果有人有任何见解我会很感激帮助。谢谢你的时间。

1 个答案:

答案 0 :(得分:1)

您正在遇到矩阵乘法的基本属性。如果你有实数4 * 5 == 5 * 4。然而,对于矩阵来说并非如此。

我有点醉,写这个答案,所以我可能会弄错,因为它恰好与自然相反:最右边的变换首先发生,左边的变换发生。

测试此功能的一种简单方法是左右尝试相机矩阵。其中一个会做你想要的:)通常将右侧的矩阵乘法视为对不同空间的变换非常有帮助。在3D中通常是MODEL * CAMERA * PROJECTION。现在你想改变CAMERA。你想要在它之前或之后进行变换。假设您通过鼠标输入INPUT的矩阵进行更改。然后你可以做INPUT * CAMERA或CAMERA * INPUT。在第一种情况下,您的参考框架是没有相机的世界,在第二种情况下,它是相机看到的世界。

您正在尝试执行与应用和撤消翻译类似的操作,但这还不够。

我希望这会有所帮助。随意跟进。但也读了矩阵数学。这是一个陡峭的学习曲线,但非常值得,从你的问题判断你非常接近:)