box2d dynamic tree

本文深入探讨了Box2DDynamicTree的构建过程,通过分析源码,解释了如何根据面积代价和继承成本来决定节点是否合并为父节点。详细介绍了插入节点的策略,以及如何通过计算左右子树的代价来选择最优路径。同时,解释了为何使用周长作为代价评估标准,以及这种选择背后的技术考量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

box2d dynamic tree
dynamic tree 是一颗 full binary trees,  即非叶子节点必须有两个子节点(注:full binary trees和大学老师讲的满二叉树,完全二叉树不同)
 
那么如果构建树?先看源码
 
 while (m_nodes[index].IsLeaf() == false)
 {
  int32 child1 = m_nodes[index].child1;
  int32 child2 = m_nodes[index].child2;

  float32 area = m_nodes[index].aabb.GetPerimeter();
  // 面积代价

  b2AABB combinedAABB;
  combinedAABB.Combine(m_nodes[index].aabb, leafAABB);
  float32 combinedArea = combinedAABB.GetPerimeter();
  // 合并后的 周长

  // Cost of creating a new parent for this node and the new leaf
  float32 cost = 2.0f * combinedArea;

  // Minimum cost of pushing the leaf further down the tree
  float32 inheritanceCost = 2.0f * (combinedArea - area);

  // Cost of descending into child1
  float32 cost1;
  if (m_nodes[child1].IsLeaf())
  {
   b2AABB aabb;
   aabb.Combine(leafAABB, m_nodes[child1].aabb);
   cost1 = aabb.GetPerimeter() + inheritanceCost;
  }
  else
  {
   b2AABB aabb;
   aabb.Combine(leafAABB, m_nodes[child1].aabb);
   float32 oldArea = m_nodes[child1].aabb.GetPerimeter();
   float32 newArea = aabb.GetPerimeter();
   cost1 = (newArea - oldArea) + inheritanceCost;
  }

  // Cost of descending into child2
  float32 cost2;
  if (m_nodes[child2].IsLeaf())
  {
   b2AABB aabb;
   aabb.Combine(leafAABB, m_nodes[child2].aabb);
   cost2 = aabb.GetPerimeter() + inheritanceCost;
  }
  else
  {
   b2AABB aabb;
   aabb.Combine(leafAABB, m_nodes[child2].aabb);
   float32 oldArea = m_nodes[child2].aabb.GetPerimeter();
   float32 newArea = aabb.GetPerimeter();
   cost2 = newArea - oldArea + inheritanceCost;
  }

  // Descend according to the minimum cost.
  if (cost < cost1 && cost < cost2)
  {
   break;
  }

  // Descend
  if (cost1 < cost2)
  {
   index = child1;
  }
  else
  {
   index = child2;
  }
 }

  box2d是采用surface area heuristic 划分场景的。 虽然采用的是getperimter, 获取aabb的周长,然后计算代价。 但可以从变量名上可以找到area, totalarea,  newarea,oldarea. 这可能是因为采用周长的代价更低的原因。

    插入思路如下:计算左右子树的代价,选择代价低的节点,如果此节点是叶子节点,将新节点插入。 如果不是,重复此步操作。

 

 
 

转载于:https://www.cnblogs.com/duzib/p/4590900.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值