Friday, September 15, 2017

行星系坐标变换 和 一些 OPENGL的感悟

这个例子是地球绕太阳,月亮同时绕地球的渲染

1.太阳为原点渲染,地球的坐标先平移,再绕原点y轴旋转渲染
2.麻烦的是月亮。月亮的坐标上传后也以原点为中心(big bang模式!opengl的模型上传之后,其局部坐标和世界坐标是重合的,后续的变换都是在世界坐标系中进行的!就像宇宙形成一样从中心大爆炸!)


    1)月亮变换第一种方法:先缩放,然后偏移(偏移距离是月亮距离原点(即太阳)的绝对距离),然后进行坐标系变换,将此时的坐标(在太阳坐标系中给出)变换到地球坐标系中去。由于地球的坐标系是在太阳坐标系的基础上,先旋转再平移得到的(注意两者都有!),所以构建两个view变换矩阵,一个是旋转,一个是平移,月亮的太阳坐标先乘以旋转再乘以平移,得到月亮在地球坐标系里的坐标。(最后为了render,还要将这个坐标变换回太阳坐标系去,同样乘以两个view矩阵,不过和第一步的是相反的方向)。总体是一个世界到local,做完旋转在回到世界的变换过程。

    2) 第二种方法,月亮的坐标先缩放,再偏移,不过此时的偏移量按照相对地球的距离进行。然后做旋转,此时月亮是围绕中心轴以相对地球的偏移在旋转(这些变换都是在太阳坐标系下进行的)。接下来将旋转之后的坐标变换到地球坐标系中去,同样需要一个旋转一个平移变换,得到月亮在地球坐标系的坐标。最后再用两个相反的矩阵将这个坐标变换会太阳坐标系用于render。整体上是一个先在世界坐标系做完旋转(注意此时的旋转半径是月亮相对地球的距离),变换到local坐标,然后再回到世界的过程。

上述变换和在hexapod设计中的坐标变换是类似的(将旋转平台的坐标变换到base坐标系中去,而base坐标系是由旋转坐标系先旋转再平移得到的,所以构建两个view变换矩阵来做变换)

要记住view变换(坐标系变换)和坐标变换之间的关系!

opengl glutPostRedisplay(void)

1用法编辑
void glutPostRedisplay(void);

2描述编辑

glutPostRedisplay 标记当前窗口需要重新绘制。通过glutMainLoop下一次循环时,窗口显示将被回调以重新显示窗口的正常面板。多次调用glutPostRedisplay,在下一个显示回调只产生单一的重新显示回调。
为了便于理解,用下面的例子[1]来说明:
假设有绘制代码:
glutDisplayFunc(display); // opengl drawing goes here
glutTimerFunc(30, drive, -1);// physics, movement equations here
glutMainLoop();
另外有代码如下:
void drive (int data)
{
glutTimerFunc(30, drive, -1);// call drive() again in 30 milliseconds
glutPostRedisplay();
}
如果有glutpostredisplay,mianloop运行的过程会像下面这样:
drive (-1);
display();
drive (-1);
display();
drive (-1);
display();
...
如果没有glutPostRedisplay,glutMainloop运行的过程会像下面这样:
drive (-1);
drive (-1);
drive (-1);
...