1.在设计地图的缩放与拖动时,发生了若缩放1/2后,拖动地图时,鼠标移动的距离是实际移动的位移的1/2。 究其原因,在于gltranslate函数的调用位置。
拖动的实现如下:将拖动前后鼠标的屏幕坐标转换为世界坐标,计算位移x后,调用gltranslate函数移动x位移。
先有如下讨论(1):
又因为缩放与拖动操作的对应性:如果先缩放地图,后拖动地图。由于opengl命令与实际操作反序,因此应该先执行拖动,后执行缩放。 但是因为缩放与拖动可在任意时间点触发,因此无法知道地图操作的具体顺序。 因此采用在modelview矩阵的按相同的顺序左乘操作命令即可(opengl命令与操作反序的原因是opengl是将当前矩阵右乘操作矩阵),且操modelview矩阵的当前矩阵仅仅为若干地图操作的结果,不包含任何其他变化。(若有视图矩阵变化部分,则将该变化放到投影矩阵里吧。 Opengl渲染的结果=投影矩阵*视图模型矩阵*坐标点)。
根据讨论(1),该解决方案在面对先缩放1/2,再拖动地图,处理流程相当于:
glUnproject()
glTranslate()
glScale(1/2);
model(); //在局部坐标系下,或者说经过变换前的世界坐标系下绘制模型
出现问题的原因在于glUnproject。glUnproject返回的坐标是model层次上的坐标,即未经过任何变化的世界坐标系。而拖动地图时,拖动的是经过缩放的坐标系。 这样,利用缩放前的距离去拖动缩放后的地图,就会导致本该移动1m(缩放前的世界坐标系下的1m)最后成了缩放后移动1m,即相当于缩放前2m的距离。
将modelview矩阵的结构改为:
[缩放n*缩放n-1。。。*缩放*缩放1]*当期矩阵*[拖动m*。。。拖动1]。
即 缩放与拖动分为两部分乘,其中每个集合内部都是逆序的。
假设当前矩阵为A,当碰到缩放n操作时,将对应的操作矩阵Sn*A即可 。然而,对于拖动矩阵,如果直接右乘,无法保证其逆序。因为你不知道拖动m何时出现。而opengl无法再上述结构中进行插入操作(事实上,新操作甚至只能插入上述操作序列的最右端)。幸好,由于拖动矩阵具有交换律。因此直接乘吧。。。。
最终解决方案:
将modelview矩阵的结构改为:
[缩放n*缩放n-1。。。*缩放*缩放1]*当期矩阵*[拖动1*。。。拖动m]。
_________________________________________________________________________
7-19:地图的缩放应该在标准坐标系下进行比较方便。 即对已经完成 模型视图映射、投影映射、坐标规范化后的数据进行操作
228



被折叠的 条评论
为什么被折叠?



