StelGeodesicGrid.cpp   StelGeodesicGrid.cpp 
/* /*
StelGeodesicGrid: a library for dividing the sphere into triangle zones StelGeodesicGrid: a library for dividing the sphere into triangle zones
by subdividing the icosahedron by subdividing the icosahedron
Author and Copyright: Johannes Gajdosik, 2006 Author and Copyright: Johannes Gajdosik, 2006
This library requires a simple Vector library, This library requires a simple Vector library,
which may have different copyright and license, which may have different copyright and license,
for example Vec3d from VecMath.hpp. for example Vec3f from VecMath.hpp.
In the moment I choose to distribute the library under the GPL, In the moment I choose to distribute the library under the GPL,
later I may choose to additionally distribute it under a more later I may choose to additionally distribute it under a more
relaxed license like the LGPL. If you want to have the library relaxed license like the LGPL. If you want to have the library
under another license, please ask me. under another license, please ask me.
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. of the License, or (at your option) any later version.
skipping to change at line 39 skipping to change at line 39
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include "StelGeodesicGrid.hpp" #include "StelGeodesicGrid.hpp"
#include <QDebug> #include <QDebug>
#include <cmath> #include <cmath>
#include <cstdlib> #include <cstdlib>
static const double icosahedron_G = 0.5*(1.0+sqrt(5.0)); static const float icosahedron_G = 0.5*(1.0+sqrt(5.0));
static const double icosahedron_b = 1.0/sqrt(1.0+icosahedron_G*icosahedron_ static const float icosahedron_b = 1.0/sqrt(1.0+icosahedron_G*icosahedron_G
G); );
static const double icosahedron_a = icosahedron_b*icosahedron_G; static const float icosahedron_a = icosahedron_b*icosahedron_G;
static const Vec3d icosahedron_corners[12] = static const Vec3f icosahedron_corners[12] =
{ {
Vec3d( icosahedron_a, -icosahedron_b, 0.0), Vec3f( icosahedron_a, -icosahedron_b, 0.0),
Vec3d( icosahedron_a, icosahedron_b, 0.0), Vec3f( icosahedron_a, icosahedron_b, 0.0),
Vec3d(-icosahedron_a, icosahedron_b, 0.0), Vec3f(-icosahedron_a, icosahedron_b, 0.0),
Vec3d(-icosahedron_a, -icosahedron_b, 0.0), Vec3f(-icosahedron_a, -icosahedron_b, 0.0),
Vec3d( 0.0, icosahedron_a, -icosahedron_b), Vec3f( 0.0, icosahedron_a, -icosahedron_b),
Vec3d( 0.0, icosahedron_a, icosahedron_b), Vec3f( 0.0, icosahedron_a, icosahedron_b),
Vec3d( 0.0, -icosahedron_a, icosahedron_b), Vec3f( 0.0, -icosahedron_a, icosahedron_b),
Vec3d( 0.0, -icosahedron_a, -icosahedron_b), Vec3f( 0.0, -icosahedron_a, -icosahedron_b),
Vec3d(-icosahedron_b, 0.0, icosahedron_a), Vec3f(-icosahedron_b, 0.0, icosahedron_a),
Vec3d( icosahedron_b, 0.0, icosahedron_a), Vec3f( icosahedron_b, 0.0, icosahedron_a),
Vec3d( icosahedron_b, 0.0, -icosahedron_a), Vec3f( icosahedron_b, 0.0, -icosahedron_a),
Vec3d(-icosahedron_b, 0.0, -icosahedron_a) Vec3f(-icosahedron_b, 0.0, -icosahedron_a)
}; };
struct TopLevelTriangle struct TopLevelTriangle
{ {
int corners[3]; // index der Ecken int corners[3]; // index der Ecken
}; };
static const TopLevelTriangle icosahedron_triangles[20] = static const TopLevelTriangle icosahedron_triangles[20] =
{ {
{{ 1, 0,10}}, // 1 {{ 1, 0,10}}, // 1
skipping to change at line 127 skipping to change at line 127
if (maxLevel > 0) if (maxLevel > 0)
{ {
for (int i=maxLevel-1;i>=0;i--) delete[] triangles[i]; for (int i=maxLevel-1;i>=0;i--) delete[] triangles[i];
delete[] triangles; delete[] triangles;
} }
delete cacheSearchResult; delete cacheSearchResult;
cacheSearchResult = NULL; cacheSearchResult = NULL;
} }
void StelGeodesicGrid::getTriangleCorners(int lev,int index, void StelGeodesicGrid::getTriangleCorners(int lev,int index,
Vec3d &h0, Ve
Vec3d &h1, c3f &h0,
Vec3d &h2) const Ve
c3f &h1,
Ve
c3f &h2) const
{ {
if (lev <= 0) if (lev <= 0)
{ {
const int *const corners = icosahedron_triangles[index].corn ers; const int *const corners = icosahedron_triangles[index].corn ers;
h0 = icosahedron_corners[corners[0]]; h0 = icosahedron_corners[corners[0]];
h1 = icosahedron_corners[corners[1]]; h1 = icosahedron_corners[corners[1]];
h2 = icosahedron_corners[corners[2]]; h2 = icosahedron_corners[corners[2]];
} }
else else
{ {
lev--; lev--;
const int i = index>>2; const int i = index>>2;
Triangle &t(triangles[lev][i]); Triangle &t(triangles[lev][i]);
switch (index&3) switch (index&3)
{ {
case 0: case 0:
{ {
Vec3d c0,c1,c2; Vec3f c0,c1,c2;
getTriangleCorners(lev,i,c0,c1,c2); getTriangleCorners(lev,i,c0,c1,c2);
h0 = c0; h0 = c0;
h1 = t.e2; h1 = t.e2;
h2 = t.e1; h2 = t.e1;
} }
break; break;
case 1: case 1:
{ {
Vec3d c0,c1,c2; Vec3f c0,c1,c2;
getTriangleCorners(lev,i,c0,c1,c2); getTriangleCorners(lev,i,c0,c1,c2);
h0 = t.e2; h0 = t.e2;
h1 = c1; h1 = c1;
h2 = t.e0; h2 = t.e0;
} }
break; break;
case 2: case 2:
{ {
Vec3d c0,c1,c2; Vec3f c0,c1,c2;
getTriangleCorners(lev,i,c0,c1,c2); getTriangleCorners(lev,i,c0,c1,c2);
h0 = t.e1; h0 = t.e1;
h1 = t.e0; h1 = t.e0;
h2 = c2; h2 = c2;
} }
break; break;
case 3: case 3:
h0 = t.e0; h0 = t.e0;
h1 = t.e1; h1 = t.e1;
h2 = t.e2; h2 = t.e2;
skipping to change at line 211 skipping to change at line 211
return (lev==1) ? index-3 : (getPartnerTriangle(lev-1, index >>2)<<2)+1; return (lev==1) ? index-3 : (getPartnerTriangle(lev-1, index >>2)<<2)+1;
case 5: case 5:
return (lev==1) ? index-5 : (getPartnerTriangle(lev-1, index >>2)<<2)+0; return (lev==1) ? index-5 : (getPartnerTriangle(lev-1, index >>2)<<2)+0;
default: default:
Q_ASSERT(0); Q_ASSERT(0);
} }
return 0; return 0;
} }
void StelGeodesicGrid::initTriangle(int lev,int index, void StelGeodesicGrid::initTriangle(int lev,int index,
const Vec3d &c0, const Vec3f
const Vec3d &c1, &c0,
const Vec3d &c2) const Vec3f
&c1,
const Vec3f
&c2)
{ {
Q_ASSERT((c0^c1)*c2 >= 0.0); Q_ASSERT((c0^c1)*c2 >= 0.0);
Triangle &t(triangles[lev][index]); Triangle &t(triangles[lev][index]);
t.e0 = c1+c2; t.e0 = c1+c2;
t.e0.normalize(); t.e0.normalize();
t.e1 = c2+c0; t.e1 = c2+c0;
t.e1.normalize(); t.e1.normalize();
t.e2 = c0+c1; t.e2 = c0+c1;
t.e2.normalize(); t.e2.normalize();
lev++; lev++;
skipping to change at line 254 skipping to change at line 254
visitTriangles(0,i, visitTriangles(0,i,
icosahedron_corners[corners[0]], icosahedron_corners[corners[0]],
icosahedron_corners[corners[1]], icosahedron_corners[corners[1]],
icosahedron_corners[corners[2]], icosahedron_corners[corners[2]],
maxVisitLevel,func,context); maxVisitLevel,func,context);
} }
} }
} }
void StelGeodesicGrid::visitTriangles(int lev,int index, void StelGeodesicGrid::visitTriangles(int lev,int index,
const Vec3d &c0, const Vec3
const Vec3d &c1, f &c0,
const Vec3d &c2, const Vec3
f &c1,
const Vec3
f &c2,
int maxVisitLevel, int maxVisitLevel,
VisitFunc *func, VisitFunc *func,
void *context) const void *context) const
{ {
(*func)(lev,index,c0,c1,c2,context); (*func)(lev,index,c0,c1,c2,context);
Triangle &t(triangles[lev][index]); Triangle &t(triangles[lev][index]);
lev++; lev++;
if (lev <= maxVisitLevel) if (lev <= maxVisitLevel)
{ {
index *= 4; index *= 4;
visitTriangles(lev,index+0,c0,t.e2,t.e1,maxVisitLevel,func,c ontext); visitTriangles(lev,index+0,c0,t.e2,t.e1,maxVisitLevel,func,c ontext);
visitTriangles(lev,index+1,t.e2,c1,t.e0,maxVisitLevel,func,c ontext); visitTriangles(lev,index+1,t.e2,c1,t.e0,maxVisitLevel,func,c ontext);
visitTriangles(lev,index+2,t.e1,t.e0,c2,maxVisitLevel,func,c ontext); visitTriangles(lev,index+2,t.e1,t.e0,c2,maxVisitLevel,func,c ontext);
visitTriangles(lev,index+3,t.e0,t.e1,t.e2,maxVisitLevel,func ,context); visitTriangles(lev,index+3,t.e0,t.e1,t.e2,maxVisitLevel,func ,context);
} }
} }
int StelGeodesicGrid::getZoneNumberForPoint(const Vec3d &v,int searchLevel) const int StelGeodesicGrid::getZoneNumberForPoint(const Vec3f &v,int searchLevel) const
{ {
for (int i=0;i<20;i++) for (int i=0;i<20;i++)
{ {
const int *const corners = icosahedron_triangles[i].corners; const int *const corners = icosahedron_triangles[i].corners;
const Vec3d &c0(icosahedron_corners[corners[0]]); const Vec3f &c0(icosahedron_corners[corners[0]]);
const Vec3d &c1(icosahedron_corners[corners[1]]); const Vec3f &c1(icosahedron_corners[corners[1]]);
const Vec3d &c2(icosahedron_corners[corners[2]]); const Vec3f &c2(icosahedron_corners[corners[2]]);
if (((c0^c1)*v >= 0.0) && ((c1^c2)*v >= 0.0) && ((c2^c0)*v > = 0.0)) if (((c0^c1)*v >= 0.0) && ((c1^c2)*v >= 0.0) && ((c2^c0)*v > = 0.0))
{ {
// v lies inside this icosahedron triangle // v lies inside this icosahedron triangle
for (int lev=0;lev<searchLevel;lev++) for (int lev=0;lev<searchLevel;lev++)
{ {
Triangle &t(triangles[lev][i]); Triangle &t(triangles[lev][i]);
i <<= 2; i <<= 2;
if ((t.e1^t.e2)*v <= 0.0) if ((t.e1^t.e2)*v <= 0.0)
{ {
// i += 0; // i += 0;
 End of changes. 12 change blocks. 
34 lines changed or deleted 43 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/