• BSP


    Brief of Binary Space Partitioning.

    Target: examine the areas where one can draw advantages of the structure supplied and study the generating process.

    Drawbacks: BSP is static and it is very expensive to modify during run-time.

    What is BSP-tree?

    In the beginning of the 90’s the main reason BSP-trees were being used was that they sorted the polygons in the scene so that you always drew back-to-front, meaning that the polygon with the lowest Z-value[*] was drawn last. There are other ways to sort the polygons so that the closest polygon is drawn last, for example the Painter’s algorithm[3], but few are as cheap as BSP-trees, because the sorting of the polygons is done during the pre-processing[*] of the map and not under run-time. The algorithm for generating a BSP-tree is actually an extension of Painter’s algorithm[5].

    How to split?

    There are several ways to split up the set of polygons into smaller subsets. For example, you can choose an arbitrary plane in space and divide the polygons by putting the ones on the positive side of the plane in the right sub tree and the polygons on the negative side in the left sub tree. The problem with this approach is that it is very difficult to find a plane that divides the polygons into two approximately equally sized sets, since there are an infinite set of planes in space. So the most common way to do this is by taking one of the polygons in the scene and dividing the polygons according to the plane that polygon defines.

    How to choose ploygon?

    When a BSP-tree is created, one has to decide whether the need is of a balanced tree, meaning that there should not be too big a difference in depth between the left and the right sub tree of each node, or try to limit the number of splits, since each split creates new polygons. If too many new polygons is created during the BSP-tree creation the graphic card will have a hard time rendering the map, thus reducing the frame rate, while a unbalanced tree will require more expensive traversal of the tree. We decided to accept a certain number of splits in order to get a more balanced tree. But the main concern was reducing the number of new polygons created.

       1: CHOOSE-DIVIDING-POLYGON
       2:  Indata:
       3:    PolygonSet – The set of polygons to search for the best dividing polygon.
       4:  Outdata:
       5:    The best dividing polygon
       6:  Effect:
       7:    Searches through the set of polygons and returns the polygons that
       8:    splits the set into the two best resulting sets. If the set is
       9:    convex no polygon can be returned.
      10:  
      11: HOOSE-DIVIDING-POLYGON (PolygonSet)
      12:   if (IS-CONVEX-SET (PolygonSet))
      13:       then return NOPOLYGON
      14:   MinRelation = MINIMUMRELATION
      15:   BestPolygon = NOPOLYGON
      16:   LeastSplits = INFINITY
      17:   BestRelation = 0
      18:   // Loop to find the polygon that best divides the set.
      19:   while(BestPolygon = NOPOLYGON)
      20:       for each polygon P1 in PolygonSet
      21:           if (Polygon P1 has not been used as divider previously
      22:               during the creation of the tree)
      23:  
      24:               // Count the number of polygons on the positive side, negative side
      25:               // of and spanning the plane defined by the current polygon.
      26: 0             NumPositive = 0, NumNegative = 0, NumSpanning = 0
      27: 1             for each polygon P2 in PolygonSet except P1
      28: 2                 Value = CALCULATE-SIDE(P1, P2)
      29: 3                 if(Value = INFRONT)
      30: 4                     NumPositive = NumPositive + 1
      31: 5                 else if(Value = BEHIND)
      32: 6                     NumNegative = NumNegative + 1
      33: 7                 else if(Value = SPANNING)
      34: 8                     NumSpanning = NumSpanning + 1
      35:  
      36:           // Calculate the relation between the number of polygons in the two
      37:           // sets divided by the current polygon.
      38: 9         if (NumPositive < NumNegative)
      39: 0             Relation = NumPositive / NumNegative
      40: 1         else
      41: 2             Relation = NumNegative / NumPositive
      42:  
      43:           // Compare the results given by the current polygon to the best this
      44:           // far. If the this polygon splits fewer polygons and the relation
      45:           // between the resulting sets is acceptable this is the new candidate
      46:           // polygon. If the current polygon splits the same amount of polygons
      47:           // as the best polygon this far and the relation between the two
      48:           // resulting sets is better -> this polygon is the new candidate
      49:           // polygon.
      50: 3         if (Relation > MinRelation && (NumSpanning < LeastSplits ||
      51:               NumSpanning = LeastSplits && Relation > BestRelation))
      52: 4            BestPolygon = P1
      53: 5            LeastSplits = NumSpanning
      54: 6            BestRelation = Relation
      55:  
      56:       // Decrease the number least acceptable relation by dividing it with
      57:       // a predefined constant.
      58: 7     MinRelation = MinRelation / MINRELATIONSCALE
      59: 8 return BestPolygon

    What is the complexity?

    Assume that the initial value for MinRelation is 1, which is the highest possible value since the relation is always between 0 and 1, so:

    1 / MINRELATIONSCALEi < 1/(n-1)
    1 < MINRELATIONSCALEi/(n-1)
    (n-1) < MINRELATIONSCALEi
    logMINRELATIONSCALE (n-1) < i

    This is no upper bound for i, but since i will be very close to logMINRELATIONSCALE (n-1) we will, for simplicity assume they are equal. Another practical assumption to make is that MINRELATIONSCALEalways should be greater than or equal to 2. Thus giving us:

    logMINRELATIONSCALE (n-1) = i MINRELATIONSCALE >= 2
    i = logMINRELATIONSCALE (n-1) < lg(n-1) = O(lg n)

    So这个算法的时间复杂度是O(n^2 *lg n), 算法中要选择恰当的MINIMUBERELATION, MINRELATIONSCALE.

    How to build BSP-Tree?

       1: ► GENERATE-BSP-TREE
       2: * Indata:
       3: *   Node - The sub tree to build of the type BSPTreeNode.
       4: *   PolygonSet – The set of polygons to create a BSP-tree from.
       5: * Outdata:
       6: *   A BSP-tree stored in the incoming node.
       7: * Effect:
       8: *   Generates a BSP-tree out of a set of polygons.
       9:  
      10: GENERATE-BSP-TREE (Node, PolygonSet)
      11: 1  if (IS-CONVEX-SET (PolygonSet))
      12: 2      Tree = BSPTreeNode (PolygonSet)
      13: 3  Divider = CHOOSE-DIVIDING-POLYGON (PolygonSet)
      14: 4  PositiveSet = {}
      15: 5  NegativeSet = {}
      16: 6  for each polygon P1 in PolygonSet
      17: 7      Value f CALCULATE-SIDE (Divider, P1)
      18: 8      if(Value = INFRONT)
      19: 9          PositiveSet = PositiveSet U P1
      20: 10     else if (Value = BEHIND)
      21: 11         NegativeSet = NegativeSet U P1
      22: 12     else if (Value = SPANNING)
      23: 13         Split_Polygon (P1, Divider, Front, Back)
      24: 14         PositiveSet = PositiveSet U Front
      25: 15         NegativeSet = NegativeSet U Back
      26: 16 GENERATE-BSP-TREE (Tree.RightChild, PositiveSet)
      27: 17 GENERATE-BSP-TREE (Tree.LeftChild, NegativeSet)

    时间复杂度T(n) = 1/2T(1/2*n) + O(n^2lgn). 由递归树求得T(n) = O(n^2lgn)

    Using BSP-Tree to draw the scene.

       1: DRAW-BSP-TREE
       2:  Indata:
       3:    Node – The node to draw.
       4:    Position – The viewer’s position.
       5:  Outdata:
       6:    None
       7:  Effect:
       8:    Draws the polygons contained in the node and its sub trees.
       9:  
      10: RAW-BSP-TREE (Node, Position)
      11:   if (IS-LEAF(Node))
      12:       DRAW-POLYGONS (Node.PolygonSet)
      13:       return
      14:  
      15:   // Calculate which sub tree the viewer is in.
      16:   Side = CLASSIFY-POINT (Node.Divider, Position)
      17:  
      18:   // If the viewer is in the right sub tree draw that tree before the
      19:   // left.
      20:   if (Side = INFRONT || Side = COINCIDING)
      21:       DRAW-BSP-TREE (Node.RightChild, Position)
      22:       DRAW-BSP-TREE (Node.LeftChild, Position)
      23:  
      24:   // Otherwise draw the left first.
      25:   else if(Value = BEHIND)
      26:       DRAW-BSP-TREE (Node.LeftChild, Position)
      27: 0     DRAW-BSP-TREE (Node.RightChild, Position)

    REFERENCE:

    http://www.devmaster.net/articles/bsp-trees/#Reference

  • 相关阅读:
    asp.net 中的viewstate用法?
    .net中 过滤 指定 字符串
    js中replace的用法
    restart
    外部函数
    JQuery实现Ajax 根据商品名称自动显示价格
    ListView中命令行按钮应用;
    GridView中获取行数和列数
    全局应用程序类Global
    如何获取gridview中模板列中控件的值?
  • 原文地址:https://www.cnblogs.com/hucn/p/2179785.html
Copyright © 2020-2023  润新知