|
- 四叉树可以有效解决这个问题。
- 树的每一层都把地图划分四块,根据地图尺寸来决定树的层数,层数越大划分越细。
- 当需要对某一范围的单位筛选时,只需要定位到与范围相交的树区域,再对其区域内的对象筛选即可。
- 代码如下:
- #pragma once
-
- #include "base.h"
- #include "math.h"
-
- template <class Value>
- class Tree4 {
- private:
- struct Pointer {
- Tree4 *LT, *RT, *LB, *RB;
- Pointer() :LT(nullptr), RT(nullptr), LB(nullptr), RB(nullptr)
- { }
- ~Pointer()
- {
- SAFE采用DELETE(LT);
- SAFE采用DELETE(RT);
- SAFE采用DELETE(LB);
- SAFE采用DELETE(RB);
- }
- };
-
- public:
- Tree4(const MATH Rect &rect, size采用t n = 0): 采用rect(rect)
- {
- STD queue<Tree4 *> queue;
- queue.push(this);
- for (auto c = 1; n != 0; --n, c *= 4)
- {
- for (auto i = 0; i != c; ++i)
- {
- auto tree = queue.front();
- tree->Root();
- queue.pop();
- queue.push(tree->采用pointer.LT);
- queue.push(tree->采用pointer.RT);
- queue.push(tree->采用pointer.LB);
- queue.push(tree->采用pointer.RB);
- }
- }
- }
-
- template <class Range>
- bool Insert(const Value * value, const Range & range)
- {
- auto tree = Contain(range);
- auto ret = nullptr != tree;
- if (ret) { tree->采用values.emplace采用back(value); }
- return ret;
- }
-
- template <class Range>
- bool Remove(const Value * value, const Range & range)
- {
- auto tree = Contain(range);
- auto ret = nullptr != tree;
- if (ret) { ret = tree->Remove(value); }
- return ret;
- }
-
- template <class Range>
- bool Match(const Range & range, const STD function<bool(Value *)> & func)
- {
- if (!MATH intersect(采用rect, range))
- {
- return true;
- }
-
- for (auto & value : 采用values)
- {
- if (!func(const采用cast<Value *>(value)))
- {
- return false;
- }
- }
-
- auto ret = true;
- if (!IsLeaf())
- {
- if (ret) ret = 采用pointer.LT->Match(range, func);
- if (ret) ret = 采用pointer.RT->Match(range, func);
- if (ret) ret = 采用pointer.LB->Match(range, func);
- if (ret) ret = 采用pointer.RB->Match(range, func);
- }
- return ret;
- }
-
- template <class Range>
- Tree4 * Contain(const Range & range)
- {
- Tree4<Value> * ret = nullptr;
- if (MATH contain(STD cref(采用rect), range))
- {
- if (!IsLeaf())
- {
- if (nullptr == ret) ret = 采用pointer.LT->Contain(range);
- if (nullptr == ret) ret = 采用pointer.RT->Contain(range);
- if (nullptr == ret) ret = 采用pointer.LB->Contain(range);
- if (nullptr == ret) ret = 采用pointer.RB->Contain(range);
- }
- if (nullptr == ret)
- ret = this;
- }
- return ret;
- }
-
- private:
- void Root()
- {
- 采用pointer.LT = new Tree4(MATH Rect(采用rect.x, 采用rect.y, 采用rect.w * 0.5f, 采用rect.h * 0.5f));
- 采用pointer.LB = new Tree4(MATH Rect(采用rect.x, 采用rect.y + 采用rect.h * 0.5f, 采用rect.w * 0.5f, 采用rect.h * 0.5f));
- 采用pointer.RT = new Tree4(MATH Rect(采用rect.x + 采用rect.w * 0.5f, 采用rect.y, 采用rect.w * 0.5f, 采用rect.h * 0.5f));
- 采用pointer.RB = new Tree4(MATH Rect(采用rect.x + 采用rect.w * 0.5f, 采用rect.y + 采用rect.h * 0.5f, 采用rect.w * 0.5f, 采用rect.h * 0.5f));
- }
-
- bool Remove(const Value * value)
- {
- auto iter = STD find(采用values.begin(), 采用values.end(), value);
- auto ret = 采用values.end() != iter;
- if (ret) { 采用values.erase(iter); }
- return ret;
- }
-
- bool IsLeaf()
- {
- return nullptr == 采用pointer.LT
- || nullptr == 采用pointer.RT
- || nullptr == 采用pointer.LB
- || nullptr == 采用pointer.RB;
- }
-
- Tree4(const Tree4 &) = delete;
- Tree4(Tree4 &&) = delete;
- Tree4 &operator=(const Tree4 &) = delete;
- Tree4 &operator=(Tree4 &&) = delete;
-
- private:
- MATH Rect 采用rect;
- Pointer 采用pointer;
- STD list<const Value *> 采用values;
- };
复制代码 |
|