随笔- 29  文章- 5  评论- 408 

    上篇文章介绍了本算法中需要用到的一些数学工具以及运算技巧,为后文打下了数学基础。本文从另一个方面着手,为后文提供存储数据的数据结构。
    在所有的数据结构书籍中一定会有这样一个公式:程序 = 算法 + 数据结构,显然这二者是每个程序员的必修课。由于对它们的研究比较深入,各种经典结构及算法已经基本定型,所以无论是在.NET还是在Java中都被封装成非常好用的类,这样就大幅提高了开发效率,并且降低了编程门槛,这都是好事。但是万不可因为它们非常容易使用就只知其然不知其所以然,一定的了解还是必要的,毕竟经典的数据结构在某些时候未必会完全符合要求,我们需要进行包装甚至是重头搭建,还好本算法使用的数据结构不那么复杂,适当的包装一下就可以了。

一、 DirectX中的两个缓冲
    如果你不是DirectX菜鸟,可以直接跳过这一段,本段是对DirectX中顶点缓冲(Vertex Buffer)和索引缓冲(Index Buffer)的概要介绍。
    在DirectX中,一切都是三角形(当然如果你非拿线段来质问我就太矫情了),所有的物体都是由大量的三角形拟合而成,这也正是本专题存在的前提。
    如果是我们来设计DirectX中的数据结构会怎样做呢?最直观的,把每个三角形的三个顶点按照顺序(DirectX中是逆时针)构成一个三元组,再把所有这些三元组组成一个大数组不就可以了。没错,DirectX正是这样做的,只不过并没有什么三元组,而是把所有的顶点一股脑的装进那个大数组,每相邻的三个为一组表示一个三角形罢了。
    上面所说的方案是DirectX支持的一种,这个大数组就是顶点缓冲,它无可挑剔的直观,但是它的缺点也是致命的:浪费了大量的存储空间。浪费在什么地方了呢?很多三角形是共用顶点的!每个顶点所占用的空间可是不菲呀,重复的那几遍毫无意义。
    很自然的,我们想到,如果把顶点缓冲当做一个没有顺序关系,没有重复的顶点池,把每个三角形顶点在这个池中的索引拿出来放到另一个数组中,像前面一样把索引三个一组的排列来表示一个三角形,会不会更好呢?

我们来算笔帐:描述空间三角形某个顶点需要三个分量,每个分量都是Double型的,在.NET中一个Double值占用8个字节,所以一个顶点需要24个字节。现假设渲染如图的一个立方体,总共有6个面,每个面需要两个三角形,总共是12个三角形,36个顶点,如果将这36个顶点一股脑的装进顶点缓冲需要6×2×3×24 = 864字节;现在换用第二种方法,顶点个数一共是8个,所以顶点缓冲需要8×24 = 192字节,三角形的个数还是那么多,所以需要有36个索引来分别代表上一种方法的36个顶点,这些索引都是其对应顶点在顶点缓冲中的索引,在这里是0~7,索引都是Integer型的,在.NET中一个Integer值占用4个字节,所以这里索引数组需要36×4 = 144字节,总共是192 + 144 = 336字节。结果很明显,采用第二种方法的空间占有量仅为第一种方法的336 / 864 = 38.9%,优势极其明显,当模型更为复杂时这种优势将更加强化,所以只有在模型极为简单的时候才使用第一种方法,毕竟直观嘛,如果模型稍微复杂一些,就要使用带有索引的方法了,索引的数组正是DirectX的索引缓冲。
    这种顶点缓冲与索引缓冲的应用,与享元模式何其相似来尔!

二、 设计数据结构
    由于该算法三角剖分出来的结果是要为DirectX提供数据的,所以我们的数据结构要能很好的与DirectX数据结构交互,因此参照DirectX数据结构设计是很自然的,况且根据前面的分析,该种设计方式也是很合理的。

VertexBuffer
IndexBuffer

    顶点缓冲中的Point2OnLine是上篇文章Point2的子类,含有一些其它属性,在这里不必关心。由于我们面对的问题是平面多边形的三角剖分,所以所有顶点不必具有三个分量,可以认为z值始终为零。

三、 例说二缓冲
    下面我们就从一个具体的例子来详细说明两个缓冲是如何配合的。
 

第一步:绘制一个多边形
第二步:利用扫描线在多边形上找到所有被扫描线扫到的点(整体思路请看《第二回:漫谈新思路,是我们自己干的时候了》
第三步:上一步找到的点已经被组织到顶点缓冲,顺序是无所谓的,但是不可以重复,上文已经说过了
第四步:第一个三角形ABD的索引按照顺序(逆时针)添加到索引缓冲
第五步:所有五个三角形的顶点索引按照顺序添加到索引缓冲
    上面的步骤中第二步和第三步是交替进行的,找到一个点后就将该点加入到顶点缓冲中,具体过程请看《第六回:寻找交点,离胜利就剩一步 之 开找》,第四第五步的详细过程请看《第七回:寻找三角形,夺取红旗》。

    终于,一切准备工作已经完成,用于算法调试的步骤显示在《第三回:实现步骤显示,一步一步看得见》
已经实现 ,数学基础在《第四回:掌握数学工具,没个好帮手怎么行》已经打下,本文又给数据存储做好了准备,下一篇文章我们将进入整个算法的最核心地带,讲述交点的寻找历程。
 posted on 2008-04-25 14:19 floodpeak 阅读(1904) 评论(20)  编辑 收藏 所属分类: 挑战系列

#1楼     回复  引用  查看    
 Justin       | 2008-04-25 14:40
 
#2楼     回复  引用  查看    
 狼Robot       | 2008-04-25 15:08
楼主牛人.
#3楼     回复  引用  查看    
 good man       | 2008-04-25 15:35
好,支持

#4楼     回复  引用  查看    
 生鱼片       | 2008-04-25 15:53
这图好酷啊
#5楼     回复  引用  查看    
 A.Z       | 2008-04-25 16:30
造福群众,请LZ转成C#版本。
#6楼     回复  引用  查看    
 墙头草       | 2008-04-25 18:06
支持楼上建议....
#7楼     回复  引用  查看    
 装配脑袋       | 2008-04-25 18:55
支持VB版^_^,壮大博客园VB技术力量
#8楼     回复  引用  查看    
 BAsil       | 2008-04-25 20:44
支持一哈
#9楼     回复  引用  查看    
 lazylu       | 2008-04-25 21:07
支持~图很PP啊~~~~使用Managed DirectX做吗?
#10楼 [楼主]    回复  引用  查看    
 floodpeak       | 2008-04-26 00:02
@Justin
@狼Robot
@good man
@生鱼片
@A.Z
@墙头草
@装配脑袋
@BAsil
@lazylu
感谢支持
再次感谢
#11楼 [楼主]    回复  引用  查看    
 floodpeak       | 2008-04-26 00:07
@A.Z
@墙头草
@装配脑袋
呵呵,我个人是比较喜欢VB.NET的,虽然我刚接触.NET时是从C#入手的
没用过VB.NET的兄弟如果有时间可以玩一玩,有很多在C#中无法体验的编程感觉,我曾经说过,用VB.NET编程有一种飞的感觉

#12楼 [楼主]    回复  引用  查看    
 floodpeak       | 2008-04-26 00:08
@lazylu
对,正是,已经做了一部分,部分效果图我会在后面的文章中秀一秀
#13楼     回复  引用  查看    
 Angel Lucifer       | 2008-04-26 00:08
偶一直特佩服对计算机图形学比较了解的人,呵呵。
顶一个。
#14楼     回复  引用  查看    
 lazylu       | 2008-04-26 12:42
太好了~~~期待一下MDX方面的大作~~
嘿嘿~~是不是人心不足蛇吞象呢^_^
#15楼     回复  引用  查看    
 badnewfish       | 2008-04-26 21:02
其实我最关心,楼主的图拿啥做的哈哈!
如同有的讲师将完技术答疑时,就有听众问ppt效果怎么实现党的。嘿嘿!
#16楼     回复  引用  查看    
 镜涛       | 2008-04-27 20:25
--引用--------------------------------------------------
Justin: <img src="http://www.cnblogs.com/Emoticons/qface/055243188.gif" alt="" />&nbsp;

--------------------------------------------------------

#17楼 [楼主]    回复  引用  查看    
 floodpeak       | 2008-04-27 21:46
@Angel Lucifer
我确实在读一些计算机图形学的东西,但是说老实话,此物颇为精深,常令我仰天长啸
#18楼 [楼主]    回复  引用  查看    
 floodpeak       | 2008-04-27 21:53
@lazylu
托管DirectX的好东东网上有不少
我也只是用一点点皮毛而已
如果有机会我会把作为初学者的一些感受写一写
#19楼 [楼主]    回复  引用  查看    
 floodpeak       | 2008-04-27 21:57
@badnewfish
多边形是从我自己实现的程序截屏下来的,在本专题的第二回有一段视频,就是在演示这个程序;图中的框子是用powerpoint2007做的,效果可以做的很炫的;图标是从网上找的一个系列,很有趣;加工当然是用ps
#20楼 [楼主]    回复  引用  查看    
 floodpeak       | 2008-04-27 21:57
@镜涛