20 #ifndef _STELSPHERICALINDEX_HPP_
21 #define _STELSPHERICALINDEX_HPP_
23 #include "StelRegionObject.hpp"
34 void insert(StelRegionObjectP obj);
39 rootNode->processIntersectingRegions(region, func);
45 rootNode->processIntersectingPointInRegions(region, func);
51 rootNode->processBoundingCapIntersectingRegions(cap, func);
57 rootNode->processContainedRegions(region, func);
61 template<
class FuncObject>
void processAll(FuncObject& func)
const
63 rootNode->processAll(func);
76 processAll<CountFunc>(func);
83 CountFunc() : nb(0) {;}
95 NodeElem(StelRegionObjectP aobj) : obj(aobj), cap(obj->getRegion()->getBoundingCap()) {;}
96 StelRegionObjectP obj;
106 QVector<NodeElem> elements;
107 QVector<Node> children;
113 Q_ASSERT(children.empty());
114 Q_ASSERT(triangle.getConvexContour().size() == 3);
116 const Vec3d& c0 = triangle.getConvexContour().at(0);
117 const Vec3d& c1 = triangle.getConvexContour().at(1);
118 const Vec3d& c2 = triangle.getConvexContour().at(2);
120 Q_ASSERT((c1^c0)*c2 >= 0.0);
121 Vec3d e0(c1[0]+c2[0], c1[1]+c2[1], c1[2]+c2[2]);
123 Vec3d e1(c2[0]+c0[0], c2[1]+c0[1], c2[2]+c0[2]);
125 Vec3d e2(c0[0]+c1[0], c0[1]+c1[1], c0[2]+c1[2]);
130 Q_ASSERT(children[0].triangle.checkValid());
132 Q_ASSERT(children[1].triangle.checkValid());
134 Q_ASSERT(children[2].triangle.checkValid());
136 Q_ASSERT(children[3].triangle.checkValid());
149 class RootNode :
public Node
152 RootNode(
int amaxObjectsPerNode,
int amaxLevel) : maxObjectsPerNode(amaxObjectsPerNode), maxLevel(amaxLevel)
156 virtual ~RootNode() {}
161 static const Vec3d vertice[6] =
163 Vec3d(0,0,1),
Vec3d(1,0,0),
Vec3d(0,1,0),
Vec3d(-1,0,0),
Vec3d(0,-1,0),
Vec3d(0,0,-1)
166 static const int verticeIndice[8][3] =
168 {0,2,1}, {0,1,4}, {0,4,3}, {0,3,2}, {5,1,2}, {5,4,1}, {5,3,4}, {5,2,3}
173 for (
int i=0;i<8;++i)
175 node.triangle =
SphericalConvexPolygon(vertice[verticeIndice[i][0]], vertice[verticeIndice[i][1]], vertice[verticeIndice[i][2]]);
176 Q_ASSERT(node.triangle.checkValid());
177 children.append(node);
182 void insert(
const NodeElem& el,
int level)
211 template<
class FuncObject>
void processAll(FuncObject& func)
const
218 void insert(Node& node,
const NodeElem& el,
int level)
220 if (node.children.isEmpty())
222 node.elements.append(el);
224 if (level<maxLevel && node.elements.size() > maxObjectsPerNode)
227 const QVector<NodeElem> nodeElems = node.elements;
228 node.elements.clear();
230 for (QVector<NodeElem>::ConstIterator iter = nodeElems.constBegin();iter != nodeElems.constEnd(); ++iter)
232 insert(node, *iter, level);
239 for (QVector<Node>::iterator iter = node.children.begin(); iter!=node.children.end(); ++iter)
241 if (((
SphericalRegion*)&(iter->triangle))->contains(el.obj->getRegion().data()))
243 insert(*iter, el, level+1);
248 node.elements.append(el);
254 foreach (
const NodeElem& el, node.elements)
256 if (region->
intersects(el.obj->getRegion().data()))
259 foreach (
const Node& child, node.children)
261 if (region->
contains(child.triangle))
271 foreach (
const NodeElem& el, node.elements)
273 if (region->
contains(el.obj->getPointInRegion()))
276 foreach (
const Node& child, node.children)
278 if (region->
contains(child.triangle))
287 foreach (
const NodeElem& el, node.elements)
289 if (cap.intersects(el.cap))
292 foreach (
const Node& child, node.children)
294 if (cap.contains(child.triangle))
296 else if (cap.intersects(child.triangle))
304 foreach (
const NodeElem& el, node.elements)
306 if (region->
contains(el.obj->getRegion().data()))
309 foreach (
const Node& child, node.children)
311 if (region->
contains(child.triangle))
319 template<
class FuncObject>
void processAll(
const Node& node, FuncObject& func)
const
321 foreach (
const NodeElem& el, node.elements)
323 foreach (
const Node& child, node.children)
328 int maxObjectsPerNode;
334 int maxObjectsPerNode;
339 #endif // _STELSPHERICALINDEX_HPP_
void processIntersectingRegions(const SphericalRegion *region, FuncObject &func) const
Process all the objects intersecting the given region using the passed function object.
void processAll(FuncObject &func) const
Process all the objects intersecting the given region using the passed function object.
unsigned int count()
Return the total number of elements in the container.
A SphericalCap is defined by a direction and an aperture.
void processIntersectingPointInRegions(const SphericalRegion *region, FuncObject &func) const
Process all the objects intersecting the given region using the passed function object.
void insert(StelRegionObjectP obj)
Insert the given object in the StelSphericalIndex.
void clear()
Remove all the elements in the container.
bool contains(const SphericalRegion *r) const
Returns whether a SphericalRegion is contained into this region.
A special case of SphericalPolygon for which the polygon is convex.
Abstract class defining a region of the sphere.
void processContainedRegions(const SphericalRegion *region, FuncObject &func) const
Process all the objects contained in the given region using the passed function object.
Container allowing to store and query SphericalRegion.
bool intersects(const SphericalRegion *r) const
Returns whether a SphericalRegion intersects with this region.
Simple abstract class defining basic methods implemented by all objects that need to be stored in a S...
A templatized 3d vector compatible with openGL.
void processBoundingCapIntersectingRegions(const SphericalCap &cap, FuncObject &func) const
Process all the objects intersecting the given region using the passed function object.