3
StelGeodesicGrid: a library for dividing the sphere into triangle zones
4
by subdividing the icosahedron
6
Author and Copyright: Johannes Gajdosik, 2006
8
This library requires a simple Vector library,
9
which may have different copyright and license,
10
for example Vec3d from VecMath.hpp.
12
In the moment I choose to distribute the library under the GPL,
13
later I may choose to additionally distribute it under a more
14
relaxed license like the LGPL. If you want to have the library
15
under another license, please ask me.
19
This library is free software; you can redistribute it and/or
20
modify it under the terms of the GNU General Public License
21
as published by the Free Software Foundation; either version 2
22
of the License, or (at your option) any later version.
24
This library is distributed in the hope that it will be useful,
25
but WITHOUT ANY WARRANTY; without even the implied warranty of
26
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27
GNU General Public License for more details.
29
You should have received a copy of the GNU General Public License
30
along with this library; if not, write to the Free Software
31
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
35
#ifndef _STELGEODESICGRID_HPP_
36
#define _STELGEODESICGRID_HPP_
38
#include "StelSphereGeometry.hpp"
40
class GeodesicSearchResult;
42
class StelGeodesicGrid
44
// Grid of triangles (zones) on the sphere with radius 1,
45
// generated by subdividing the icosahedron.
46
// level 0: just the icosahedron, 20 zones
47
// level 1: 80 zones, level 2: 320 zones, ...
48
// Each zone has a unique integer number in the range
49
// [0,getNrOfZones()-1].
51
StelGeodesicGrid(int maxLevel);
52
~StelGeodesicGrid(void);
55
int getMaxLevel(void) const {return maxLevel;}
57
static int nrOfZones(int level)
58
{return (20<<(level<<1));} // 20*4^level
60
int getNrOfZones(void) const {return nrOfZones(maxLevel);}
62
//! Return the position of the 3 corners for the triangle at the given level and index
63
void getTriangleCorners(int lev, int index, Vec3d& c0, Vec3d& c1, Vec3d& c2) const;
64
//! Return the index of the partner triangle with which to form a paralelogram
65
int getPartnerTriangle(int lev, int index) const;
67
typedef void (VisitFunc)(int lev,int index,
73
void visitTriangles(int maxVisitLevel, VisitFunc *func,void *context) const;
75
//! Find the zone number in which a given point lies.
76
//! prerequisite: v*v==1
77
//! When the point lies on the border of two or more zones,
78
//! one such zone is returned (always the same one,
79
//! because the algorithm is deterministic).
80
int searchZone(const Vec3d &v,int searchLevel) const;
82
//! Find all zones that lie fully(inside) or partly(border)
83
//! in the intersection of the given half spaces.
84
//! The result is accurate when (0,0,0) lies on the border of
85
//! each half space. If this is not the case,
86
//! the result may be inaccurate, because it is assumed, that
87
//! a zone lies in a half space when its 3 corners lie in this half space.
88
//! inside[l] points to the begin of an integer array of size nrOfZones(l),
89
//! border[l] points to one after the end of the same integer array.
90
//! The array will be filled from the beginning with the inside zone numbers
91
//! and from the end with the border zone numbers of the given level l
92
//! for 0<=l<=getMaxLevel().
93
//! inside[l] will not contain zones that are already contained
94
//! in inside[l1] for some l1 < l.
95
//! In order to restrict search depth set maxSearchLevel < maxLevel,
96
//! for full search depth set maxSearchLevel = maxLevel,
97
void searchZones(const StelGeom::ConvexS& convex,
98
int **inside,int **border,int maxSearchLevel) const;
100
//! Return a search result matching the given spatial region
101
//! The result is cached, meaning that it is very fast to search the same region consecutively
102
//! @return a GeodesicSearchResult instance which must be used with GeodesicSearchBorderIterator and GeodesicSearchInsideIterator
103
const GeodesicSearchResult* search(const StelGeom::ConvexS& convex, int maxSearchLevel) const;
105
//! Convenience function returning a search result matching the given spatial region
106
//! The result is cached, meaning that it is very fast to search the same region consecutively
107
//! @return a GeodesicSearchResult instance which must be used with GeodesicSearchBorderIterator and GeodesicSearchInsideIterator
108
const GeodesicSearchResult* search(const Vec3d &e0,const Vec3d &e1,const Vec3d &e2,const Vec3d &e3,int maxSearchLevel) const;
111
const Vec3d& getTriangleCorner(int lev, int index, int cornerNumber) const;
112
void initTriangle(int lev,int index,
116
void visitTriangles(int lev,int index,
122
void *context) const;
123
void searchZones(int lev,int index,
124
const StelGeom::ConvexS& convex,
125
const int *indexOfUsedHalfSpaces,
126
const int halfSpacesUsed,
127
const bool *corner0_inside,
128
const bool *corner1_inside,
129
const bool *corner2_inside,
130
int **inside,int **border,int maxSearchLevel) const;
135
Vec3d e0,e1,e2; // Seitenmittelpunkte
137
Triangle **triangles;
138
// 20*(4^0+4^1+...+4^n)=20*(4*(4^n)-1)/3 triangles total
141
//! A cached search result used to avoid doing twice the same search
142
mutable GeodesicSearchResult* cacheSearchResult;
143
mutable int lastMaxSearchlevel;
144
mutable StelGeom::ConvexS lastSearchRegion;
147
class GeodesicSearchResult
150
GeodesicSearchResult(const StelGeodesicGrid &grid);
151
~GeodesicSearchResult(void);
152
void print(void) const;
154
friend class GeodesicSearchInsideIterator;
155
friend class GeodesicSearchBorderIterator;
156
friend class StelGeodesicGrid;
158
void search(const StelGeom::ConvexS& convex, int maxSearchLevel);
160
const StelGeodesicGrid &grid;
166
class GeodesicSearchBorderIterator
169
GeodesicSearchBorderIterator(const GeodesicSearchResult &ar,int alevel)
170
: r(ar),level((alevel<0)?0:(alevel>ar.grid.getMaxLevel())
171
?ar.grid.getMaxLevel():alevel),
172
end(ar.zones[GeodesicSearchBorderIterator::level]+
173
StelGeodesicGrid::nrOfZones(GeodesicSearchBorderIterator::level))
175
void reset(void) {index = r.border[level];}
176
int next(void) // returns -1 when finished
177
{if (index < end) {return *index++;} return -1;}
179
const GeodesicSearchResult &r;
181
const int *const end;
186
class GeodesicSearchInsideIterator
189
GeodesicSearchInsideIterator(const GeodesicSearchResult &ar,int alevel)
191
maxLevel((alevel<0)?0:(alevel>ar.grid.getMaxLevel())?ar.grid.getMaxLevel():alevel)
194
int next(void); // returns -1 when finished
196
const GeodesicSearchResult &r;
206
#endif // _STELGEODESICGRID_HPP_