Use after Think
程序员不是源程序
随笔- 29 文章- 5 评论- 437
博客园
首页
新随笔
新文章
联系
管理
订阅
第五回:设计数据结构,存好了数据好干活
上篇文章
介绍了本算法中需要用到的一些数学工具以及运算技巧,为后文打下了数学基础。本文从另一个方面着手,为后文提供存储数据的数据结构。
在所有的数据结构书籍中一定会有这样一个公式:程序 = 算法 + 数据结构,显然这二者是每个程序员的必修课。由于对它们的研究比较深入,各种经典结构及算法已经基本定型,所以无论是在.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
1
Public
Class VertexBuffer
Class
VertexBuffer
2
Private
points
As
New
List(
Of
Point2OnLine)
'
点数组
3
4
Default
Public
ReadOnly
Property Point()
Property
Point(
ByVal
i
As
Integer
)
As
Point2OnLine
5
Get
6
If
(i
<
points.Count
AndAlso
i
>=
0
)
Then
7
Return
points(i)
8
Else
9
MsgBox
(
"
数组越界
"
)
10
Return
Nothing
11
End
If
12
End
Get
13
End Property
14
15
Public
Function add()
Function
add(
ByVal
point
As
Point2OnLine)
As
Integer
'
添加一个点
16
Dim
index
As
Integer
=
Me
.seek(point)
'
在点数组中寻找该点
17
If
(index
>=
0
)
Then
'
如果返回值大于等于零,该点已经存在
18
If
(
Not
points(index).Style.Contains(point.Style))
Then
'
如果该点的style属性有新内容
19
points(index).Style
&=
"
,
"
&
point.Style
20
End
If
21
Return
index
'
返回已经存在点的索引
22
End
If
23
points.Add(point)
'
将新点插入点数组
24
Return
points.Count
-
1
'
返回新点的索引
25
End Function
26
27
Public
Function seek()
Function
seek
(
ByVal
point
As
Point2OnLine)
As
Integer
'
在点数组中寻找某点,如果存在返回索引,如不存在返回-1
28
For
i
As
Integer
=
0
To
points.Count
-
1
29
If
(points(i).Equals(point))
Then
30
Return
i
31
End
If
32
Next
33
Return
-
1
34
End Function
35
36
37
End Class
38
IndexBuffer
1
Public
Class IndexBuffer
Class
IndexBuffer
2
Private
indexes
As
New
List(
Of
Integer
)
'
索引数组
3
4
Public
Sub add()
Sub
add(
ByVal
index
As
Integer
)
5
indexes.Add(index)
6
End Sub
7
8
Public
ReadOnly
Property Count()
Property
Count()
As
Integer
9
Get
10
Return
Me
.indexes.Count
11
End
Get
12
End Property
13
14
Default
Public
ReadOnly
Property Index()
Property
Index(
ByVal
i
As
Integer
)
As
Integer
15
Get
16
If
(i
<
indexes.Count
AndAlso
i
>=
0
)
Then
17
Return
indexes(i)
18
Else
19
MsgBox
(
"
数组越界
"
)
20
Return
Nothing
21
End
If
22
End
Get
23
End Property
24
25
End Class
26
顶点缓冲中的Point2OnLine是
上篇文章
Point2的子类,含有一些其它属性,在这里不必关心。由于我们面对的问题是平面多边形的三角剖分,所以所有顶点不必具有三个分量,可以认为z值始终为零。
三、 例说二缓冲
下面我们就从一个具体的例子来详细说明两个缓冲是如何配合的。
第一步:绘制一个多边形
第二步:利用扫描线在多边形上找到所有被扫描线扫到的点(整体思路请看
《第二回:漫谈新思路,是我们自己干的时候了》
)
第三步:上一步找到的点已经被组织到顶点缓冲,顺序是无所谓的,但是不可以重复,上文已经说过了
第四步:第一个三角形ABD的索引按照顺序(逆时针)添加到索引缓冲
第五步:所有五个三角形的顶点索引按照顺序添加到索引缓冲
上面的步骤中第二步和第三步是交替进行的,找到一个点后就将该点加入到顶点缓冲中,具体过程请看《第六回:寻找交点,离胜利就剩一步 之 开找》,第四第五步的详细过程请看《第七回:寻找三角形,夺取红旗》。
终于,一切准备工作已经完成,用于算法调试的步骤显示在
《第三回:实现步骤显示,一步一步看得见》
已经实现 ,数学基础在
《第四回:掌握数学工具,没个好帮手怎么行》
已经打下,本文又给数据存储做好了准备,
下一篇
文章我们将进入整个算法的最核心地带,讲述交点的寻找历程。
Tag标签:
挑战系列
,
三角剖分
posted on 2008-04-25 14:19
floodpeak
阅读(2111)
评论(21)
编辑
收藏
网摘
所属分类:
挑战系列
评论
1360802
#1楼
回复
引用
查看
Justin
| 2008-04-25 14:40
http://www.cnblogs.com/Emoticons/qface/055243188.gif" alt="" />
#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"
" target="_new">
http://www.cnblogs.com/Emoticons/qface/055243188.gif"
alt="" />
--------------------------------------------------------
#17楼
[
楼主
]
回复
引用
查看
floodpeak
| 2008-04-27 21:46
@Angel Lucifer
我确实在读一些计算机图形学的东西,但是说老实话,此物颇为精深,常令我仰天长啸
http://www.cnblogs.com/Emoticons/yoyocici/224023962.gif" alt="" />
#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
@镜涛
?
#21楼
回复
引用
LensFlare(平平淡淡)[未注册用户]
| 2008-11-04 14:30
楼主之名,如雷贯耳啊~~~
刷新评论列表
刷新页面
返回页首
发表评论
昵称:
[登录]
[注册]
主页:
邮箱:
(仅博主可见)
验证码:
看不清,换一个
评论内容:
登录
注册
[使用Ctrl+Enter键快速提交评论]
0
1170936
链接:
切换模板
导航:
网站首页
社区
新闻
博问
闪存
网摘
招聘
找找看
Google搜索
China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
China-Pub 计算机绝版图书按需印刷服务
相关文章:
最新IT新闻:
上海电信计划2012年80%用户实现100M带宽
数万名网友签名抗议星际争霸2取消局域网功能
Silverlight打造杰克逊纪念专题
传诺基亚正在开发Android手机
7月编程语言排行榜
相关链接:
公告
clicked
<
2008年4月
>
日
一
二
三
四
五
六
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
8
9
10
与我联系
发短消息
搜索
常用链接
我的随笔
我的空间
我的短信
我的评论
更多链接
我的文章
我的参与
我的新闻
最新评论
我的标签
留言簿
给我留言
查看留言
我参加的小组
每日一句英语
设计模式
程序员音乐空间
jQuery
博客园精华集出版小组
博客园期刊团队
我的标签
转载系列
(9)
挑战系列
(8)
三角剖分
(7)
经典文章
(6)
讨论
(3)
二进制时钟
(3)
设计模式
(2)
备忘录
(2)
语言
(1)
认证
(1)
更多
随笔分类
(20)
面向对象(3)
挑战系列(8)
转载系列(9)
随笔档案
(31)
2008年7月 (1)
2008年6月 (1)
2008年5月 (6)
2008年4月 (8)
2008年3月 (6)
2008年2月 (7)
2008年1月 (1)
2007年11月 (1)
相册
SuperMap2007技术大会
订阅我
关注博客
TerryLee
xiaotie
刘润
刘未鹏|C++的罗浮宫
吕震宇
伍迷
张逸
我的好友
jillzhang
积分与排名
积分 - 61778
排名 - 995
最新评论
1. re: 激烈讨论:我最常用的设计模式
设计模式是前人总结的一个方法,要说常用,其实对OO的开发者,抽象就是最常用的,设计模式只是给你的一个参考,告诉让某种问题简单化你可以这样或那样抽象。所以设计模式没常用之分,应该提写代码经常会遇到什么问...
--Max Gan
2. re: 在VB.NET中撒娇的Hashtable
呵呵,嗯啊,没有 () 和 {} 噢...
--小 海
阅读排行榜
1. 激烈讨论:我最常用的设计模式(3075)
2. 激烈讨论:我身边的IT认证(3022)
3. 第一回:回望经典,看看别人是怎么干的(2841)
4. 4月语言排行榜出炉,祝贺Visual Basic同比上升两名(2818)
5. 如何摆脱写文档时截屏的困扰(2548)
评论排行榜
1. 激烈讨论:我身边的IT认证(66)
2. 激烈讨论:我的语言路线(54)
3. 4月语言排行榜出炉,祝贺Visual Basic同比上升两名(38)
4. 在VB.NET中撒娇的Hashtable(35)
5. 激烈讨论:我最常用的设计模式(30)