|

楼主 |
发表于 2007-7-10 22:21:00
|
显示全部楼层
Re: BSP树
如何建立BSP树
介绍
给定三维空间中的一组多边形,我们要建立的BSP树应该包含它们当中的每一个。建立BSP树的算法是非常简单的:
1.选择分割平面
如何建立BSP树
介绍
给定三维空间中的一组多边形,我们要建立的BSP树应该包含它们当中的每一个。建立BSP树的算法是非常简单的:
1. 选择分割平面
分割平面的选择依赖于BSP树将如何被使用,以及空间中多边形的排序条件。某些情况下,使用空间中某个多边形所在的平面进行分割(叫做自动分割)。在另外一些情况下,与坐标轴垂直的平面常被用做分割平面。
在任何一种情况下,对选择分割平面的策略进行评估都是很重要的。一个很普遍的想法是让BSP树的结构尽量趋近于平衡二叉树,但是这样做是有代价的。要实现一个完全平衡的BSP树,当一个多边形与分割平面相交时,它必须被分割成两部分。一个糟糕的分割平面选择策略会产生很多这样的分割。
2. 分割多边形集合
需要根据步骤1中选择的分割平面将多边形集合分解成两个子集。如果一个多边形完全处于分割平面的一侧,只需要把它添加对应的子集中。如果与分割平面相交,先将其分成两部分,再分别添加到两个子集中。
3. 何时停止分割
判断建立BSP树的递归过程在什么条件下停止,也是与具体的应用有关的。可以在接点包含的多边形数目小于某个界限时停止,也可以当BSP树的深度超过某个界限时停止。
伪代码
struct BSP_tree
{
plane partition;
list polygons;
BSP_tree *front, *back;
};
这个结构体定义在下面的讨论中将被一直使用。它表示BSP树的一个接点,包含有一个分割平面,处于分割平面的多边形列表,以及指向子接点的指针。
void Buld_BSP_Tree( BSP_tree *tree, list polygons )
{
polygon *root = polygons.Get_From_List();
tree->partition = root->Get_Plane();
tree->polygons.Add_To_List( root );
list front_list, back_list;
polygon *poly;
while( ( poly = polygons.Get_From_List() ) != 0 )
{
int result = tree->partition.Classify_polygon(poly);
switch( result )
{
case COINCIDENT: // 共面
tree->polygons.Add_To_List(poly);
break;
case IN_BACK_OF:
back_list.Add_To_List(poly);
break;
case IN_FRONT_OF
front_list.Add_To_List(poly);
break;
case SPANNING:
polygon *front_piece, *back_piece;
split_Polygon( poly, tree->partition, front_piece, back_piece );
back_list.Add_To_List( back_piece );
front_list.Add_To_List( front_piece );
break;
}
}
if( !front_list.Is->Empty_List() )
{
tree->front = new BSP_tree;
Build_BSP_Tree( tree->front, front_list );
}
if( !back_list->Is_Empty_List() )
{
tree->back = new BSP_tree;
Build_BSP_Tree( tree->back, back_list );
}
}
Buld_BSP_Tree函数根据以上说明的步骤递归地建立BSP树。它使用输入的多边形列表中的第一个多边形所在的平面作为分割平面,假定此列表中的每一个多边形都为凸多边形。
很明显,通过更合理的分割平面选择策略,这个函数可以得到改进,以后将详细为大家阐述。
待续。。。 |
|