2013-03-24 65 views
2

好吧,这是一个非常具体的问题,必须在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; 

哪里方向,位置和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创建表示一个4×4矩阵2维阵列([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

您正在运行矩阵乘法的基本属性。如果你有真实的数字4 * 5 == 5 * 4。尽管如此,矩阵并不是这样。

我有点醉了写这个答案,所以我可能会弄错它,因为它只是感觉自然的相反:最右边的变换发生的第一个,最左边的一个。

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

您正在尝试做类似的操作和撤消翻译,但这还不够。

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