我正在使用OpenGL,恰好是Cocos3d,在iPhone / iPad项目中显示地球仪。我希望用户能够用手指旋转地球仪。 只围绕一个轴旋转工作正常,但我不知道如何一起解决3轴......
捕捉手指运动也有效 - >我得到2D(x / y)值,但是如何在3D旋转中转换它们?
答案 0 :(得分:2)
想象一下,在窗口的中心是三维球体(不是椭圆形),它接触窗口的边缘。它位于屏幕空间,而不是世界空间。 “屏幕空间”表示如果您的窗口为640x480,则无论您的模型视图/投影矩阵如何,球体都位于x = 320,y = 240且半径为240(min(width,height)/2
)。
当用户点击按下鼠标按钮时,他/她选择球体上的点。如果click在该球体之外,则初始点移动到球体边界。我们称之为pointA
。当用户拖动鼠标时,鼠标位置标记用户想要该初始点的位置。我们称之为pointB
。
现在对于一个球体来说,计算第一个两个的第三个坐标非常容易,因为R^2 = X^2+y^2+z^2
所以你可以计算初始点(pointA
)的第三个坐标和当前点的第三个坐标({ {1}})。现在使用两个点,您可以计算从球体中心(pointB
)到点(O
)的两个向量。现在,由于您有两个向量,您可以使用它们来计算旋转轴(使用叉积= vectorOA = pointA - O; vectorOB = pointB - O
)和旋转角度(使用标准化向量的点积上的acos = rotationAxis = normalize(vecOA x vecOB);
)。使用轴和角度,您可以在屏幕空间中构建旋转矩阵,然后可以将其转换为您想要的空间并应用于对象。
该技术通常被称为“轨迹球”。它已在microsoft DirectX SDK的一些示例中使用,您应该能够在NVidia OpenGL SDK中的某处找到它。因此,如果您不理解解释,我建议您使用sdk并调查任何允许您使用鼠标旋转对象的示例。
答案 1 :(得分:0)
一种简单的方法是简单地将绕Y轴的旋转设置为要旋转的translationInView
x组件,并将围绕X轴的旋转设置为translationInView
y组件。由于旋转值以弧度为单位,您可能必须将平移除以一定量。我通常发现给用户2个自由度是足够的,但是如果你确实需要允许用户围绕z轴旋转,你可能需要考虑使用UIRotationGestureRecognizer
来单独处理这种情况。
CGPoint translation = [sender translationInView:self.view];
_rotationY = translation.x / 100.0f;
_rotationX = translation.y / 100.0f;