首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >根据网格的局部坐标旋转网格

根据网格的局部坐标旋转网格
EN

Stack Overflow用户
提问于 2013-02-03 01:10:27
回答 1查看 203关注 0票数 0

我有一个平面在一个三维世界,它的方向是以任何方式保存(例如俯仰,偏航和滚动)。现在,当我想让飞机向左转的时候,但是glRotatef不做这个工作,因为它坚持全局坐标,不关心飞机的旋转,简单地改变偏航也没有帮助,因为这与飞机的实际旋转也没有关系,只有当飞机直接飞向地平线时,这才意味着“左”。我需要的是这样的:

代码语言:javascript
复制
    float pitch = 10 , yaw = 20, roll = 30;        //some initial values
    Turn(&pitch, &yaw, &roll ,  5, 0 , 0 )   //calculate new pitch, yaw and roll as if 
    //the plane had turned 5 degrees to the right (relative to its current orientation and roll!)
    //pitch, yaw and roll are updated to reflect the new orientation.

许多人建议使用四元数,但我不知道如何将它们实现为一个旋转函数(其中一个工作示例是Blitz3D,它有一个用于全局旋转的"RotateEntity“函数,如glRotatef和基于方向的旋转"TurnEntity”)--我认为函数内部的工作方式如下:

  • 将音调、偏航、滚动转换为四元数,如EulerToQuat in OpenGL + SDL rotation around local axis
  • 使用四元数执行局部旋转(没有找到源)
  • 将四元数转换回偏航、滚转、俯仰(没有找到源)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-02-03 20:31:41

我最终解决了这个问题,切换到为每艘船随身携带一个矩阵。只有在需要时才计算俯仰、偏航和滚转,这很少是这样的。最后,glRotatef执行任务--只需将其应用于已经旋转的矩阵--并保存结果,这样更改就不会被删除。

下面的代码是我在包含x、y、z、Matrix16、dx、dy、dz的船艇结构上实现的。(请注意,所有ship数组都必须使用IdentityMatrix初始化):

代码语言:javascript
复制
//*************************** Turn Ship **********************************
void TurnShip(long nr,float yaw, float pitch=0,float roll=0) {
  //Turns ship by pitch, yaw and roll degrees.
  glMatrixMode(GL_MODELVIEW);

  glLoadMatrixf(&ship[nr].Matrix[0]); 
  glRotatef(yaw,0,1,0);  
  glGetFloatv(GL_MODELVIEW_MATRIX,&ship[nr].Matrix[0]);

  glLoadMatrixf(&ship[nr].Matrix[0]); 
  glRotatef(pitch,1,0,0); 
  glGetFloatv(GL_MODELVIEW_MATRIX,&ship[nr].Matrix[0]);

  glLoadMatrixf(&ship[nr].Matrix[0]); 
  glRotatef(roll,0,0,1); 
  glGetFloatv(GL_MODELVIEW_MATRIX,&ship[nr].Matrix[0]);  
}

该函数的作用是加载存储在简单浮点数数组中的船只矩阵,对其进行操作,然后将其保存回数组。在游戏的图形部分,这个数组将加载glLoadMatrixf,因此将应用于船舶,没有任何麻烦或数学。

代码语言:javascript
复制
//*************************** Accelerate Ship relative to own orientation **
void AccelerateShip(long nr,float speedx,float speedy, float speedz)   
{   //use speedz to move object "forward".
ship[nr].dx+= speedx*ship[nr].Matrix[0];   //accelerate sidewards (x-vector)
ship[nr].dy+= speedx*ship[nr].Matrix[1];  //accelerate sidewards (x-vector)
ship[nr].dz+= speedx*ship[nr].Matrix[2]; //accelerate sidewards (x-vector)

ship[nr].dx+= speedy*ship[nr].Matrix[4];   //accelerate upwards (y-vector)
ship[nr].dy+= speedy*ship[nr].Matrix[5];  //accelerate upwards (y-vector)
ship[nr].dz+= speedy*ship[nr].Matrix[6]; //accelerate upwards (y-vector)

ship[nr].dx+= speedz*ship[nr].Matrix[8];   //accelerate forward (z-vector)
ship[nr].dy+= speedz*ship[nr].Matrix[9];  //accelerate forward (z-vector)
ship[nr].dz+= speedz*ship[nr].Matrix[10]; //accelerate forward (z-vector)
}  

这是我今天学到的最好的部分--教程中经常没有告诉你的部分,因为它们都是关于数学的--,我可以把指向、左边和前面的向量从矩阵中拉出来,并对它们施加加速度,这样我的船就可以向左、右、下、下、加速和刹车-- glRotatef关心它们,所以它们总是被更新,而我们身边根本不涉及数学:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14668456

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档