27 #include <tulip/Rectangle.h>
28 #include <tulip/Coord.h>
36 template <
class TYPE>
class QuadTreeNode {
49 QuadTreeNode(
const tlp::Rectangle<float> &box):_box(box) {
50 assert(_box.isValid());
52 for(
int i=0; i<4; ++i)
59 for(
int i=0; i<4; ++i)
60 if (children[i] != NULL)
delete children[i];
65 void insert(
const tlp::Rectangle<float> &box,
const TYPE
id) {
66 assert(box.isValid());
67 assert(_box.isValid());
73 Vec2f subBox((_box[0]+_box[1])/2.f);
75 if( !((subBox == _box[0]) || (subBox == _box[1]))) {
76 for (
int i=0; i<4; ++i) {
77 if (getChildBox(i).isInside(box)) {
78 QuadTreeNode *child=getChild(i);
81 child->insert(box,
id);
83 entities.push_back(
id);
90 entities.push_back(
id);
98 void getElements(
const tlp::Rectangle<float> &box, std::vector<TYPE> &result)
const {
99 assert(box.isValid());
100 assert(_box.isValid());
102 if (_box.intersect(box)) {
103 for (
size_t i=0; i<entities.size(); ++i) {
104 result.push_back(entities[i]);
107 for (
unsigned int i=0; i<4; ++i) {
108 if (children[i]!=NULL)
109 children[i]->getElements(box, result);
117 void getElements(std::vector<TYPE> &result)
const {
118 for (
size_t i=0; i<entities.size(); ++i) {
119 result.push_back(entities[i]);
122 for (
unsigned int i=0; i<4; ++i) {
123 if (children[i]!=NULL)
124 children[i]->getElements(result);
137 void getElementsWithRatio(
const tlp::Rectangle<float> &box, std::vector<TYPE> &result,
float ratio = 1000.)
const {
138 assert(_box.isValid());
139 assert(box.isValid());
141 if (_box.intersect(box)) {
142 float xRatio = (box[1][0] - box[0][0]) / (_box[1][0] - _box[0][0]) ;
143 float yRatio = (box[1][1] - box[0][1]) / (_box[1][1] - _box[0][1]);
146 if (xRatio < ratio || yRatio < ratio) {
147 for (
size_t i=0; i<entities.size(); ++i) {
148 result.push_back(entities[i]);
151 for (
unsigned int i=0; i<4; ++i) {
152 if (children[i]!=NULL)
153 children[i]->getElementsWithRatio(box, result, ratio);
160 if (entities.size() > 0) {
161 result.push_back(entities[0]);
166 for (
unsigned int i=0; i<4; ++i) {
167 if (children[i]!=NULL && children[i]->_box.intersect(box)) {
170 children[i]->getElementsWithRatio(box, result, ratio);
181 QuadTreeNode* getChild(
int i) {
182 if (children[i] == 0) {
183 Rectangle<float> box (getChildBox(i));
185 if(box[0] ==_box[0] && box[1]==_box[1])
188 children[i] =
new QuadTreeNode<TYPE>(box);
194 Rectangle<float> getChildBox(
int i) {
195 assert(_box.isValid());
207 I[0] = (_box[0][0] + _box[1][0]) / 2.;
211 E[1] = (_box[0][1] + _box[1][1]) / 2.;
224 return Rectangle<float>(_box[0], F);
228 return Rectangle<float>(I, G);
232 return Rectangle<float>(F, _box[1]);
236 return Rectangle<float>(E, H);
239 tlp::error() <<
"ERROR" << __PRETTY_FUNCTION__ << std::endl;
244 QuadTreeNode *children[4];
245 std::vector<TYPE> entities;
246 tlp::Rectangle<float> _box;