private bool CheckPointInside(Bound b, QTNodeType type) { switch (type) { case QTNodeType.Root: return((b.X < Bound.X + Bound.Width / 2) && (b.X > Bound.X - Bound.Width / 2) && (b.Y < Bound.Y + Bound.Height / 2) && (b.Y > Bound.Y - Bound.Height / 2)); case QTNodeType.LB: return((b.X < Bound.X) && (b.X > Bound.X - Bound.Width / 2) && (b.Y < Bound.Y) && (b.Y > Bound.Y - Bound.Height / 2)); case QTNodeType.LT: return((b.X < Bound.X) && (b.X > Bound.X - Bound.Width / 2) && (b.Y < Bound.Y + Bound.Height / 2) && (b.Y > Bound.Y)); case QTNodeType.RB: return((b.X < Bound.X + Bound.Width / 2) && (b.X > Bound.X) && (b.Y < Bound.Y) && (b.Y > Bound.Y - Bound.Height / 2)); case QTNodeType.RT: return((b.X < Bound.X + Bound.Width / 2) && (b.X > Bound.X) && (b.Y < Bound.Y + Bound.Height / 2) && (b.Y > Bound.Y)); default: throw new NotImplementedException("未指定的QTNodeType"); } }
public QNode(Bound bound, int depth, QNode father, QTree qTree, QTNodeType type) { this.Bound = bound; this.Depth = depth; this.Father = father; this.BelongedTree = qTree; this.Type = type; ObjList = new List <Obstacle>(); ChildList = new List <QNode>(); }
public void InsertObj(Obstacle obj) { // 遇到最大深度的叶子,直接添加,不再递归 if (Depth == BelongedTree.MaxDepth || ObjList.Count() < BelongedTree.MaxObjCnt) { AddObj(obj); return; } #region 检测与节点的几个子节点相交 List <bool> _bList = new List <bool> { CheckIntersection(obj.Bound, QTNodeType.LT), CheckIntersection(obj.Bound, QTNodeType.RT), CheckIntersection(obj.Bound, QTNodeType.RB), CheckIntersection(obj.Bound, QTNodeType.LB) }; int _intersectionTimes = 0; foreach (bool b in _bList) { _intersectionTimes += b ? 1 : 0; } if (_intersectionTimes >= 2) //要添加的物体与多个子节点相交 { // 直接加入父节点 AddObj(obj); return; } else if (_intersectionTimes == 1) // 在子节点的位置内 { QNode _node; for (int i = 0; i < 4; i++) { if (_bList[i]) { QTNodeType _type = (QTNodeType)i; _node = GetNode((QTNodeType)i); if (_node == null) { _node = new QNode(GenBound(_type), Depth + 1, this, BelongedTree, _type); ChildList.Add(_node); _node.AddObj(obj); } else { _node.InsertObj(obj); } } } } else { throw new Exception("该物体不在树的范围内"); } #endregion }
private QNode GetNode(QTNodeType type) { foreach (QNode node in ChildList) { if (node.Type == type) { return(node); } } return(null); }
private Bound GenBound(QTNodeType type) { switch (type) { case QTNodeType.LT: return(GenLT()); case QTNodeType.RT: return(GenRT()); case QTNodeType.RB: return(GenRB()); case QTNodeType.LB: return(GenLB()); default: throw new Exception("不支持的type类型"); } }
private bool CheckIntersection(Bound b, QTNodeType type) { Bound _nb; switch (type) { case QTNodeType.LT: _nb = GenLT(); break; case QTNodeType.RT: _nb = GenRT(); break; case QTNodeType.RB: _nb = GenRB(); break; case QTNodeType.LB: _nb = GenLB(); break; default: throw new NotImplementedException("未指定的QTNodeType"); } float[] rec1 = { b.X - b.Width / 2, b.Y - b.Height / 2, b.X + b.Width / 2, b.Y + b.Height / 2, }; float[] rec2 = { _nb.X - _nb.Width / 2, _nb.Y - _nb.Height / 2, _nb.X + _nb.Width / 2, _nb.Y + _nb.Height / 2, }; return(!(rec1[2] <= rec2[0] || rec2[2] <= rec1[0] || rec1[3] <= rec2[1] || rec2[3] <= rec1[1])); }
public QNode(List <Obstacle> intersectionObjs, Bound bound, int depth, QNode father, QTree qTree, QTNodeType type) { this.Bound = bound; this.Depth = depth; this.Father = father; this.BelongedTree = qTree; this.Type = type; ObjList = new List <Obstacle>(); ChildList = new List <QNode>(); List <Obstacle> _LTlist = new List <Obstacle>(); List <Obstacle> _RTlist = new List <Obstacle>(); List <Obstacle> _RBlist = new List <Obstacle>(); List <Obstacle> _LBlist = new List <Obstacle>(); List <Obstacle> _Rootlist = new List <Obstacle>(); List <List <Obstacle> > _AllLists = new List <List <Obstacle> > { _LTlist, _RTlist, _RBlist, _LBlist, _Rootlist }; foreach (Obstacle obj in intersectionObjs) { if (obj.isLoaded == false) { #region 检测物体与几个子节点相交 List <bool> _blist = new List <bool> { CheckIntersection(obj.Bound, QTNodeType.LT), CheckIntersection(obj.Bound, QTNodeType.RT), CheckIntersection(obj.Bound, QTNodeType.RB), CheckIntersection(obj.Bound, QTNodeType.LB) }; int _intersectionTimes = 0; foreach (bool b in _blist) { _intersectionTimes += b ? 1 : 0; } #endregion #region 该物体穿过多个子节点 if (_intersectionTimes >= 2) { _Rootlist.Add(obj); } #endregion #region 完全在某个子节点内 else if (_intersectionTimes == 1) { for (int i = 0; i < 4; i++) { if (_blist[i]) { _AllLists[i].Add(obj); break; } } } #endregion else { throw new Exception("正在检测父节点外的物体"); } } } int _totalCnt = 0; foreach (List <Obstacle> list in _AllLists) { _totalCnt += list.Count(); } if (_totalCnt <= BelongedTree.MaxObjCnt || Depth >= BelongedTree.MaxDepth) { #region 直接全部放入父节点 foreach (List <Obstacle> list in _AllLists) { foreach (Obstacle obj in list) { AddObj(obj); } } #endregion } else { #region 父节点物体放入根节点,子节点物体继续向下递归 foreach (Obstacle obj in _Rootlist) { AddObj(obj); } #region 递归创建四个节点 for (int i = 0; i < 4; i++) { if (_AllLists[i].Count() != 0) { QTNodeType _type = (QTNodeType)i; ChildList.Add(new QNode(_AllLists[i], GenBound(_type), depth + 1, this, BelongedTree, _type)); } } #endregion #endregion } }