Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opengl es 基于二维手势/运动的三维旋转(OpenGL/Cocos3D)_Opengl Es_Mouse_Rotation_Cocos3d - Fatal编程技术网

Opengl es 基于二维手势/运动的三维旋转(OpenGL/Cocos3D)

Opengl es 基于二维手势/运动的三维旋转(OpenGL/Cocos3D),opengl-es,mouse,rotation,cocos3d,Opengl Es,Mouse,Rotation,Cocos3d,我使用OpenGL,确切地说是Cocos3d,在iPhone/iPad项目中显示地球仪。我希望用户能够用手指旋转地球仪。 只绕一个轴旋转很好,但我不知道如何解决三个轴的所有问题 捕捉手指运动也可以->我得到2D(x/y)值,但如何在3D旋转中转换这些值?想象一下,在窗口的中心是3D球体(不是椭圆),它接触到窗口的边缘。它位于屏幕空间,而不是世界空间。“屏幕空间”表示,如果您的窗口为640x480,则球体位于x=320,y=240,半径为240(min(width,height)/2),无论您的模

我使用OpenGL,确切地说是Cocos3d,在iPhone/iPad项目中显示地球仪。我希望用户能够用手指旋转地球仪。 只绕一个轴旋转很好,但我不知道如何解决三个轴的所有问题


捕捉手指运动也可以->我得到2D(x/y)值,但如何在3D旋转中转换这些值?

想象一下,在窗口的中心是3D球体(不是椭圆),它接触到窗口的边缘。它位于屏幕空间,而不是世界空间。“屏幕空间”表示,如果您的窗口为640x480,则球体位于x=320,y=240,半径为240(
min(width,height)/2
),无论您的模型视图/投影矩阵如何

当用户单击并按下鼠标按钮时,他/她选择球体上的点。如果单击位于该球体外部,则初始点将移动到球体边界中。让我们把这一点称为a点。当用户拖动鼠标时,鼠标位置会标记用户希望初始点所在的位置。让我们称之为
点b

现在对于一个球体来说,计算给定前两个的第三个坐标非常容易,因为
R^2=X^2+y^2+z^2
,所以可以计算初始点(
pointA
)的第三个坐标和当前点(
pointB
)的第三个坐标。现在,使用两个点,您可以计算从球体中心(
O
)到点(
vectorOA=pointA-O;vectorOB=pointB-O
)的两个向量。既然有了两个向量,就可以使用它们来计算旋转轴(使用叉积=
rotationAxis=normalize(vecOA x vecOB);
)和旋转角度(使用acos对规范化向量的点积=
acos(dot(normalize(vecOA),normalize(vecOB))
).使用轴和角度可以在屏幕空间中构建旋转矩阵,然后可以将旋转矩阵转换为所需的空间并应用于对象


这种技术通常被称为“轨迹球”。它已在microsoft DirectX SDK中的一些示例中使用,您应该可以在NVidia OpenGL SDK中找到它。因此,如果您不理解解释,我建议您抓住任一SDK并研究任何允许您使用鼠标旋转对象的示例。

一个简单的方法是简单地将围绕Y轴的旋转设置为de>TranslationViewx组件旋转以及围绕x轴旋转到
TranslationView
y组件。由于旋转值以弧度为单位,您可能需要将平移除以一定量。我通常认为给用户2个自由度就足够了,但如果您确实需要允许用户旋转关于Z轴,您可能需要考虑使用<代码> UIORATAUTIONEURURE EngLognase<代码>来分别处理该情况。

CGPoint translation = [sender translationInView:self.view];
_rotationY = translation.x / 100.0f;
_rotationX = translation.y / 100.0f;

+1用于轨迹球。用一些漂亮的图片解释: