Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/44.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.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
Iphone 如何使用glRotatef()和GLTRANSTALEF()在三维世界中进行增量移动_Iphone_Objective C_Opengl Es_Translate_Glrotate - Fatal编程技术网

Iphone 如何使用glRotatef()和GLTRANSTALEF()在三维世界中进行增量移动

Iphone 如何使用glRotatef()和GLTRANSTALEF()在三维世界中进行增量移动,iphone,objective-c,opengl-es,translate,glrotate,Iphone,Objective C,Opengl Es,Translate,Glrotate,我有一些3D模型,我用OpenGL在3D空间中渲染,我在移动“角色”(即相机)时遇到了一些麻烦,在这个世界中进行旋转和平移 我从一些外部事件(用户输入的图像或来自GPS+指南针设备的数据)接收输入(即移动坐标/旋转坐标),事件类型为旋转或平移 我编写了此方法来管理这些事件: - (void)moveThePlayerPositionTranslatingLat:(double)translatedLat Long:(double)translatedLong andRotating:(doubl

我有一些3D模型,我用OpenGL在3D空间中渲染,我在移动“角色”(即相机)时遇到了一些麻烦,在这个世界中进行旋转和平移

我从一些外部事件(用户输入的图像或来自GPS+指南针设备的数据)接收输入(即移动坐标/旋转坐标),事件类型为旋转或平移

我编写了此方法来管理这些事件:

- (void)moveThePlayerPositionTranslatingLat:(double)translatedLat Long:(double)translatedLong andRotating:(double)degrees{

    [super startDrawingFrame];
    if (degrees != 0)
    {
        glRotatef(degrees, 0, 0, 1);
    }

    if (translatedLat != 0)
    {
        glTranslatef(translatedLat, -translatedLong, 0);
    }

   [self redrawView];
}
然后在重画视图中,我实际绘制了场景和模型。有点像:

glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

NSInteger nModels = [models count];

for (NSInteger i = 0; i < nModels; i++) 
{
    MD2Object * mdobj = [models objectAtIndex:i];
    glPushMatrix();
    double * deltas = calloc(sizeof(double),2);

    deltas[0] = currentCoords[0] - mdobj.modelPosition[0];
    deltas[1] = currentCoords[1] - mdobj.modelPosition[1];

    glTranslatef(deltas[0], -deltas[1], 0);

    free(deltas);
    [mdobj setupForRenderGL];
    [mdobj renderGL];   
    [mdobj cleanupAfterRenderGL];
    glPopMatrix();

}
[super drawView];
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
NSInteger nModels=[模型计数];
对于(NSInteger i=0;i
问题是,当平移一个旋转事件一个接一个地被调用时:例如,当我以增量方式旋转一些迭代(仍然围绕原点),然后我平移并最终再次旋转,但最后一次旋转似乎不是围绕当前(平移)位置,而是围绕旧位置(旧的起源)。我很清楚,当转换顺序颠倒时,会发生这种情况,但我相信,在绘制一幅画之后,新的世界中心是由翻译后的系统给出的


我遗漏了什么?我该如何解决这个问题?(任何对OpenGL的引用都将不胜感激)

听起来这里发生了一些事情:

首先,你需要意识到旋转是围绕原点发生的。因此,当你平移然后旋转时,你不是围绕你认为是原点的东西旋转,而是围绕新的原点,即T-10(通过平移的倒数变换的原点)

第二,你要做的事情比你真正需要的要难一些。你可能要考虑的是使用。你本质上给它在你的场景中的一个位置和你的场景中的一个点看一个“UP”矢量,它将正确地设置场景。要正确使用它,跟踪你的相机所在的位置,调用它。向量p和向量n(表示法线…表示您正在查看的方向)和u(您的上方向向量)。如果n和u是正交向量(即,它们彼此正交且具有单位长度),则更高级的功能将更容易实现。如果这样做,您可以计算r=nxu(您的“右”向量),这将是与其他两个正交的法向量。然后“看”p+n,并提供u作为上向量

理想情况下,n、u和r具有某种标准形式,例如:

n = <0, 0, 1>
u = <0, 1, 0>
r = <1, 0, 0>
n=
u=
r=

然后递增地累积旋转,并将它们应用于定向向量的正则形式。您可以使用或来累积旋转(我非常欣赏四元数方法用于各种类型).

我建议不要在事件处理程序中进行累积转换,而是在内部存储转换的当前值,然后只转换一次,但我不知道这是否是您想要的行为

伪代码:

someEvent(lat, long, deg)
{
  currentLat += lat;
  currentLong += long;
  currentDeg += deg;
}

redraw()
{
  glClear()
  glRotatef(currentDeg, 0, 0, 1);
  glTranslatef(currentLat, -currentLong, 0);
  ... // draw stuff
}

反转转换顺序时会出现什么问题?如果先执行glTranslatef(),然后执行glRotatef())首先旋转对象,而不是平移对象,否则如果顺序颠倒,则首先平移对象,然后旋转对象。首先看一下这里,我认识到我进行了额外的平移,而这不是必需的,事实上,在事件处理程序中,我旋转并平移整个场景(=变换视图)在显示模式下,我画的对象就像它们在本地坐标系中一样(计算全局玩家位置和它们的位置之间的差异,并根据这些值进行转换)。我想说,如果我删除事件1,它将正确运行。我明白了你的观点,这是一种防止变换重叠的方法(我猜需要一个glPushMatrix()/glPopMatrix()来隔离每个元素转换)。顺便说一句,如果您在这里谈论的是性能,那么情况就不是这样了,因为在每次事件中,我都需要重新绘制视图,并且使用有限的NSOperationQueue保持较低的频率。是的,问题是重叠的变换。您所做的是这样的:稍微平移、旋转、再次旋转、平移、旋转等等。由于前面的平移,每个旋转现在都使用不同的旋转中心。如果我没弄错的话,这不是您想要的。因此,您必须累积变换的参数,并且只按照您希望的确切顺序变换一次。或者您必须在每次旋转之前“撤消”以前的平移(通过应用反向平移)。