坐标变换是OpenGL最基本功能之一,然而却不容易讲清楚,网上已有的教程好象都没有做到这一点。
其实弄懂坐标变换的关键是理解什么是“眼睛坐标系”(eye coordinate system) 和“目标坐标系”(object coordinate system),以及各个API函数使用的是哪套坐标:是“眼睛坐标”还是“目标坐标”。
所谓“眼睛坐标系”就是“全局坐标系”,可以这样设想:以窗口中心为原点,水平向右为+x轴,竖直向上为+y轴,垂直于屏幕指向我们为+z轴。长度单位这样来定:
窗口范围按此单位恰好是(-1,-1)-(1,1)。
所谓“目标坐标系”就是“局部坐标系”。在下面我们简称眼睛坐标系为ECS,目标
坐标系为OCS。点的“眼睛坐标”为EC, “目标坐标”为OC。
任何时候OpenGL都保存着一个当前的OCS,在初始条件下,OCS与ECS是重合的,但
我们可以对“目标坐标系”作各种变换: 平移、伸缩、旋转。经过这些变换之后, OCS与ECS不再重合。
非常重要的一点:glVertex3f所用的坐标是OC而不是EC。
为什么要这样设计API呢?因为我们一般习惯于在一个合适的局部坐标系中作图, 然后把它通过坐标变换放到合适的位置或者转到合适的角度。
比如我们要在(xc,yc)-(xc+dx,yc+dy)这样一个框子里画一条正弦曲线,我们更喜欢先在(0,0)-(1,1)范围内画这条曲线,然后把它先伸缩到(0,0)-(dx,dy)的范围, 再平移(xc,yc)。这个过程如果用ECS和OCS的观点来看,平移和伸缩的顺序正好反过来:
(1)开始时,调用glLoadIdentity(),OCS0与ECS重合
(2)调用glTranslatef(xc,yc,0),OCS0平移,变成OCS1
(3)调用glScalef(dx,dy,0),OCS1伸缩,变成OCS2
(4)调用glBegin(),glVertex3f(),glEnd(),在OCS2中作图
No comments:
Post a Comment