20 #ifndef _STELSPHERICALINDEXMULTIRES_HPP_
21 #define _STELSPHERICALINDEXMULTIRES_HPP_
23 #define MAX_INDEX_LEVEL 8
25 #include "StelRegionObject.hpp"
26 #include "StelSphericalIndex.hpp"
37 void insert(StelRegionObjectP obj);
42 for (
int i=1;i<MAX_INDEX_LEVEL;++i)
44 const RootNode* node = treeForRadius[i-1];
46 node->processIntersectingRegions(region, func);
51 template<
class FuncObject>
void processAll(FuncObject& func)
const
53 for (
int i=1;i<MAX_INDEX_LEVEL;++i)
55 const RootNode* node = treeForRadius[i-1];
57 node->processAll(func);
67 NodeElem(StelRegionObjectP aobj) : obj(aobj), cap(obj->getRegion()->getBoundingCap()) {;}
68 StelRegionObjectP obj;
77 QVector<NodeElem> elements;
78 QVector<Node> children;
84 Q_ASSERT(children.empty());
85 Q_ASSERT(triangle.getConvexContour().size() == 3);
87 const Vec3d& c0 = triangle.getConvexContour().at(0);
88 const Vec3d& c1 = triangle.getConvexContour().at(1);
89 const Vec3d& c2 = triangle.getConvexContour().at(2);
91 Q_ASSERT((c1^c0)*c2 >= 0.0);
92 Vec3d e0(c1[0]+c2[0], c1[1]+c2[1], c1[2]+c2[2]);
94 Vec3d e1(c2[0]+c0[0], c2[1]+c0[1], c2[2]+c0[2]);
96 Vec3d e2(c0[0]+c1[0], c0[1]+c1[1], c0[2]+c1[2]);
101 Q_ASSERT(children[0].triangle.checkValid());
103 Q_ASSERT(children[1].triangle.checkValid());
105 Q_ASSERT(children[2].triangle.checkValid());
107 Q_ASSERT(children[3].triangle.checkValid());
113 class RootNode :
public Node
116 RootNode(
double amargin,
int amaxObjectsPerNode,
int amaxLevel) : maxObjectsPerNode(amaxObjectsPerNode), maxLevel(amaxLevel), margin(amargin)
123 static const Vec3d vertice[6] =
125 Vec3d(0,0,1),
Vec3d(1,0,0),
Vec3d(0,1,0),
Vec3d(-1,0,0),
Vec3d(0,-1,0),
Vec3d(0,0,-1)
128 static const int verticeIndice[8][3] =
130 {0,2,1}, {0,1,4}, {0,4,3}, {0,3,2}, {5,1,2}, {5,4,1}, {5,3,4}, {5,2,3}
135 for (
int i=0;i<8;++i)
137 node.triangle =
SphericalConvexPolygon(vertice[verticeIndice[i][0]], vertice[verticeIndice[i][1]], vertice[verticeIndice[i][2]]);
138 Q_ASSERT(node.triangle.checkValid());
139 children.append(node);
144 void insert(
const NodeElem& el,
int level)
156 template<
class FuncObject>
void processAll(FuncObject& func)
const
163 void insert(Node& node,
const NodeElem& el,
int level)
165 if (node.children.isEmpty())
167 node.elements.append(el);
169 if (level>=maxLevel && node.elements.size() >= maxObjectsPerNode)
172 const QVector<NodeElem> nodeElems = node.elements;
173 for (QVector<NodeElem>::ConstIterator iter = nodeElems.begin();iter != nodeElems.end(); ++iter)
175 insert(node, *iter, level+1);
177 node.elements.clear();
183 for (QVector<Node>::iterator iter = node.children.begin(); iter!=node.children.end(); ++iter)
185 if (iter->triangle.contains(el.cap.n))
187 insert(*iter, el, level+1);
197 foreach (
const NodeElem& el, node.elements)
199 if (region->intersects(el.obj->getRegion()))
202 foreach (
const Node& child, node.children)
204 if (region->contains(node.triangle))
206 else if (region->intersects(node.triangle))
212 template<
class FuncObject>
void processAll(
const Node& node, FuncObject& func)
const
214 foreach (
const NodeElem& el, node.elements)
216 foreach (
const Node& child, node.children)
221 int maxObjectsPerNode;
229 int maxObjectsPerNode;
232 RootNode* treeForRadius[MAX_INDEX_LEVEL];
234 double cosRadius[MAX_INDEX_LEVEL];
237 #endif // _STELSPHERICALINDEXMULTIRES_HPP_