OctahedronPolygon.cpp   OctahedronPolygon.cpp 
skipping to change at line 20 skipping to change at line 20
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
*/ */
#include "StelUtils.hpp" #include <QFile>
#include "OctahedronPolygon.hpp"
#include "StelSphereGeometry.hpp"
#include "glues.h" #include "glues.h"
#include <QFile> #include "OctahedronPolygon.hpp"
#include "StelSphereGeometry.hpp"
#include "StelUtils.hpp"
const Vec3d OctahedronPolygon::sideDirections[] = { Vec3d(1,1,1), Vec3d( 1,1,-1),Vec3d(-1,1,1),Vec3d(-1,1,-1), const Vec3d OctahedronPolygon::sideDirections[] = { Vec3d(1,1,1), Vec3d( 1,1,-1),Vec3d(-1,1,1),Vec3d(-1,1,-1),
Vec3d(1,-1,1),Vec3d(1,-1,-1),Vec3d(-1,-1,1),Vec3d(-1,-1,-1)}; Vec3d(1,-1,1),Vec3d(1,-1,-1),Vec3d(-1,-1,1),Vec3d(-1,-1,-1)};
inline bool intersectsBoundingCap(const Vec3d& n1, double d1, const Vec3d& n2, double d2) inline bool intersectsBoundingCap(const Vec3d& n1, double d1, const Vec3d& n2, double d2)
{ {
const double a = d1*d2 - n1*n2; const double a = d1*d2 - n1*n2;
return d1+d2<=0. || a<=0. || (a<=1. && a*a <= (1.-d1*d1)*(1.-d2*d2)) ; return d1+d2<=0. || a<=0. || (a<=1. && a*a <= (1.-d1*d1)*(1.-d2*d2)) ;
} }
skipping to change at line 96 skipping to change at line 97
foreach (const EdgeVertex& v, *this) foreach (const EdgeVertex& v, *this)
{ {
//res += QString("[") + v.vertex.toString() + "],"; //res += QString("[") + v.vertex.toString() + "],";
StelUtils::rectToSphe(&ra, &dec, v.vertex); StelUtils::rectToSphe(&ra, &dec, v.vertex);
res += QString("[") + QString::number(ra*180./M_PI, 'g', 12) + "," + QString::number(dec*180./M_PI, 'g', 12) + "," + (v.edgeFlag ? QStr ing("true"): QString("false")) + "],"; res += QString("[") + QString::number(ra*180./M_PI, 'g', 12) + "," + QString::number(dec*180./M_PI, 'g', 12) + "," + (v.edgeFlag ? QStr ing("true"): QString("false")) + "],";
} }
res[res.size()-1]=']'; res[res.size()-1]=']';
return res; return res;
}; };
OctahedronPolygon::OctahedronPolygon(const QVector<Vec3d>& contour) : fillC achedVertexArray(StelVertexArray::Triangles), outlineCachedVertexArray(Stel VertexArray::Lines) OctahedronPolygon::OctahedronPolygon(const QVector<Vec3d>& contour)
{ {
sides.resize(8); sides.resize(8);
appendSubContour(SubContour(contour)); appendSubContour(SubContour(contour));
tesselate(WindingPositive); tesselate(WindingPositive);
updateVertexArray(); updateVertexArray();
} }
OctahedronPolygon::OctahedronPolygon(const QVector<QVector<Vec3d> >& contou rs) : fillCachedVertexArray(StelVertexArray::Triangles), outlineCachedVerte xArray(StelVertexArray::Lines) OctahedronPolygon::OctahedronPolygon(const QVector<QVector<Vec3d> >& contou rs)
{ {
sides.resize(8); sides.resize(8);
foreach (const QVector<Vec3d>& contour, contours) foreach (const QVector<Vec3d>& contour, contours)
appendSubContour(SubContour(contour)); appendSubContour(SubContour(contour));
tesselate(WindingPositive); tesselate(WindingPositive);
updateVertexArray(); updateVertexArray();
} }
OctahedronPolygon::OctahedronPolygon(const SubContour& initContour) OctahedronPolygon::OctahedronPolygon(const SubContour& initContour)
{ {
sides.resize(8); sides.resize(8);
appendSubContour(initContour); appendSubContour(initContour);
tesselate(WindingPositive); tesselate(WindingPositive);
updateVertexArray(); updateVertexArray();
} }
OctahedronPolygon::OctahedronPolygon(const QList<OctahedronPolygon>& octs) : fillCachedVertexArray(StelVertexArray::Triangles), outlineCachedVertexArr ay(StelVertexArray::Lines) OctahedronPolygon::OctahedronPolygon(const QList<OctahedronPolygon>& octs)
{ {
sides.resize(8); sides.resize(8);
foreach (const OctahedronPolygon& oct, octs) foreach (const OctahedronPolygon& oct, octs)
{ {
for (int i=0;i<8;++i) for (int i=0;i<8;++i)
{ {
Q_ASSERT(oct.sides.size()==8); Q_ASSERT(oct.sides.size()==8);
sides[i] += oct.sides[i]; sides[i] += oct.sides[i];
} }
tesselate(WindingPositive); tesselate(WindingPositive);
skipping to change at line 235 skipping to change at line 236
sides[i] += resultSides[i]; sides[i] += resultSides[i];
} }
} }
// Return the area in squared degrees. // Return the area in squared degrees.
double OctahedronPolygon::getArea() const double OctahedronPolygon::getArea() const
{ {
// Use Girard's theorem for each subtriangles // Use Girard's theorem for each subtriangles
double area = 0.; double area = 0.;
Vec3d v1, v2, v3; Vec3d v1, v2, v3;
const QVector<Vec3d>& trianglesArray = getFillVertexArray().vertex; const QVector<Vec3d>& trianglesArray = fillVertices();
Q_ASSERT(getFillVertexArray().primitiveType==StelVertexArray::Triang
les);
for (int i=0;i<trianglesArray.size()/3;++i) for (int i=0;i<trianglesArray.size()/3;++i)
{ {
area += OctahedronPolygon::sphericalTriangleArea(trianglesAr ray.at(i*3), trianglesArray.at(i*3+1), trianglesArray.at(i*3+2)); area += OctahedronPolygon::sphericalTriangleArea(trianglesAr ray.at(i*3), trianglesArray.at(i*3+1), trianglesArray.at(i*3+2));
} }
return area; return area;
} }
// Return a point located inside the polygon. // Return a point located inside the polygon.
Vec3d OctahedronPolygon::getPointInside() const Vec3d OctahedronPolygon::getPointInside() const
{ {
const QVector<Vec3d>& trianglesArray = getFillVertexArray().vertex; const QVector<Vec3d>& trianglesArray = fillVertices();
Q_ASSERT(getFillVertexArray().primitiveType==StelVertexArray::Triang
les);
Q_ASSERT(!trianglesArray.isEmpty()); Q_ASSERT(!trianglesArray.isEmpty());
Vec3d res(trianglesArray[0]); Vec3d res(trianglesArray[0]);
res+=trianglesArray[1]; res+=trianglesArray[1];
res+=trianglesArray[2]; res+=trianglesArray[2];
res.normalize(); res.normalize();
return res; return res;
} }
void OctahedronPolygon::append(const OctahedronPolygon& other) void OctahedronPolygon::append(const OctahedronPolygon& other)
{ {
skipping to change at line 378 skipping to change at line 377
inline void unprojectOctahedron(Vec3d& v, const Vec3d& sideDirection) inline void unprojectOctahedron(Vec3d& v, const Vec3d& sideDirection)
{ {
Q_ASSERT(v[2]<0.0000001); Q_ASSERT(v[2]<0.0000001);
v[2]=(1.-sideDirection*v)/sideDirection[2]; v[2]=(1.-sideDirection*v)/sideDirection[2];
v.normalize(); v.normalize();
} }
void OctahedronPolygon::updateVertexArray() void OctahedronPolygon::updateVertexArray()
{ {
Q_ASSERT(sides.size()==8); Q_ASSERT(sides.size()==8);
fillCachedVertexArray.vertex.clear(); fillCachedVertexArray.clear();
outlineCachedVertexArray.vertex.clear(); outlineCachedVertexArray.clear();
Q_ASSERT(sides.size()==8); Q_ASSERT(sides.size()==8);
// Use GLUES tesselation functions to transform the polygon into a l ist of triangles // Use GLUES tesselation functions to transform the polygon into a l ist of triangles
GLUEStesselator* tess = gluesNewTess(); GLUEStesselator* tess = gluesNewTess();
#ifndef NDEBUG #ifndef NDEBUG
gluesTessCallback(tess, GLUES_TESS_BEGIN, (GLvoid(*)()) &checkBeginT rianglesCallback); gluesTessCallback(tess, GLUES_TESS_BEGIN, (GLvoid(*)()) &checkBeginT rianglesCallback);
#endif #endif
gluesTessCallback(tess, GLUES_TESS_VERTEX_DATA, (GLvoid(*)()) &verte xTrianglesCallback); gluesTessCallback(tess, GLUES_TESS_VERTEX_DATA, (GLvoid(*)()) &verte xTrianglesCallback);
gluesTessCallback(tess, GLUES_TESS_EDGE_FLAG, (GLvoid(*)()) &noOpCal lback); gluesTessCallback(tess, GLUES_TESS_EDGE_FLAG, (GLvoid(*)()) &noOpCal lback);
gluesTessCallback(tess, GLUES_TESS_ERROR, (GLvoid(*)()) &errorCallba ck); gluesTessCallback(tess, GLUES_TESS_ERROR, (GLvoid(*)()) &errorCallba ck);
skipping to change at line 409 skipping to change at line 408
QVector<Vec3d> res = tesselateOneSideTriangles(tess, sidenb) ; QVector<Vec3d> res = tesselateOneSideTriangles(tess, sidenb) ;
Q_ASSERT(res.size()%3==0); // There should be only tria ngles here Q_ASSERT(res.size()%3==0); // There should be only tria ngles here
for (int j=0;j<=res.size()-3;j+=3) for (int j=0;j<=res.size()-3;j+=3)
{ {
// Post processing, GLU seems to sometimes output tr iangles oriented in the wrong direction.. // Post processing, GLU seems to sometimes output tr iangles oriented in the wrong direction..
// Get rid of them in an ugly way. TODO Need to find the real cause. // Get rid of them in an ugly way. TODO Need to find the real cause.
if (((sidenb&1)==0 ? if (((sidenb&1)==0 ?
isTriangleConvexPositive2D(res.at(j+2), res.at(j+1), res.at(j)) : isTriangleConvexPositive2D(res.at(j+2), res.at(j+1), res.at(j)) :
isTriangleConvexPositive2D(res.at(j), res.at(j+1), r es.at(j+2)))) isTriangleConvexPositive2D(res.at(j), res.at(j+1), r es.at(j+2))))
{ {
fillCachedVertexArray.vertex+=res.at(j); fillCachedVertexArray += res.at(j);
unprojectOctahedron(fillCachedVertexArray.ve unprojectOctahedron(fillCachedVertexArray.la
rtex.last(), sideDirection); st(), sideDirection);
fillCachedVertexArray.vertex+=res.at(j+1); fillCachedVertexArray += res.at(j+1);
unprojectOctahedron(fillCachedVertexArray.ve unprojectOctahedron(fillCachedVertexArray.la
rtex.last(), sideDirection); st(), sideDirection);
fillCachedVertexArray.vertex+=res.at(j+2); fillCachedVertexArray += res.at(j+2);
unprojectOctahedron(fillCachedVertexArray.ve unprojectOctahedron(fillCachedVertexArray.la
rtex.last(), sideDirection); st(), sideDirection);
} }
else else
{ {
// Discard vertex.. // Discard vertex..
//qDebug() << "Found a fucking CW triangle"; //qDebug() << "Found a fucking CW triangle";
} }
} }
// Now compute the outline contours, getting rid of non edge segments // Now compute the outline contours, getting rid of non edge segments
EdgeVertex previous; EdgeVertex previous;
foreach (const SubContour& c, sides[sidenb]) foreach (const SubContour& c, sides[sidenb])
{ {
Q_ASSERT(!c.isEmpty()); Q_ASSERT(!c.isEmpty());
previous = c.first(); previous = c.first();
unprojectOctahedron(previous.vertex, sideDirection); unprojectOctahedron(previous.vertex, sideDirection);
for (int j=0;j<c.size()-1;++j) for (int j=0;j<c.size()-1;++j)
{ {
if (previous.edgeFlag || c.at(j+1).edgeFlag) if (previous.edgeFlag || c.at(j+1).edgeFlag)
{ {
outlineCachedVertexArray.vertex.appe nd(previous.vertex); outlineCachedVertexArray.append(prev ious.vertex);
previous=c.at(j+1); previous=c.at(j+1);
unprojectOctahedron(previous.vertex, sideDirection); unprojectOctahedron(previous.vertex, sideDirection);
outlineCachedVertexArray.vertex.appe nd(previous.vertex); outlineCachedVertexArray.append(prev ious.vertex);
} }
else else
{ {
previous=c.at(j+1); previous=c.at(j+1);
unprojectOctahedron(previous.vertex, sideDirection); unprojectOctahedron(previous.vertex, sideDirection);
} }
} }
// Last point connects with first point // Last point connects with first point
if (previous.edgeFlag || c.first().edgeFlag) if (previous.edgeFlag || c.first().edgeFlag)
{ {
outlineCachedVertexArray.vertex.append(previ outlineCachedVertexArray.append(previous.ver
ous.vertex); tex);
outlineCachedVertexArray.vertex.append(c.fir outlineCachedVertexArray.append(c.first().ve
st().vertex); rtex);
unprojectOctahedron(outlineCachedVertexArray unprojectOctahedron(outlineCachedVertexArray
.vertex.last(), sideDirection); .last(), sideDirection);
} }
} }
} }
gluesDeleteTess(tess); gluesDeleteTess(tess);
computeBoundingCap(); computeBoundingCap();
#ifndef NDEBUG #ifndef NDEBUG
// Check that all triangles are properly oriented // Check that all triangles are properly oriented
QVector<Vec3d> c; QVector<Vec3d> c;
c.resize(3); c.resize(3);
for (int j=0;j<fillCachedVertexArray.vertex.size()/3;++j) for (int j=0;j<fillCachedVertexArray.size()/3;++j)
{ {
c[0]=fillCachedVertexArray.vertex.at(j*3); c[0]=fillCachedVertexArray.at(j*3);
c[1]=fillCachedVertexArray.vertex.at(j*3+1); c[1]=fillCachedVertexArray.at(j*3+1);
c[2]=fillCachedVertexArray.vertex.at(j*3+2); c[2]=fillCachedVertexArray.at(j*3+2);
Q_ASSERT(SphericalConvexPolygon::checkValidContour(c)); Q_ASSERT(SphericalConvexPolygon::checkValidContour(c));
} }
#else #else
// If I don't let this like that, the bahaviour will fail in Release mode!!!! // If I don't let this like that, the behaviour will fail in Release mode!!!!
// It is either a bug in GCC either a memory problem which appears o nly when optimizations are activated. // It is either a bug in GCC either a memory problem which appears o nly when optimizations are activated.
QVector<Vec3d> c; QVector<Vec3d> c;
c.resize(3); c.resize(3);
#endif #endif
} }
struct OctTessLineLoopCallbackData struct OctTessLineLoopCallbackData
{ {
SubContour result; //! Contains the res ulting tesselated vertices. SubContour result; //! Contains the res ulting tesselated vertices.
QVector<SubContour> resultList; QVector<SubContour> resultList;
skipping to change at line 641 skipping to change at line 640
return false; return false;
OctahedronPolygon resOct(*this); OctahedronPolygon resOct(*this);
resOct.inPlaceUnion(mpoly); resOct.inPlaceUnion(mpoly);
return resOct.getArea()-getArea()<0.00000000001; return resOct.getArea()-getArea()<0.00000000001;
} }
bool OctahedronPolygon::contains(const Vec3d& p) const bool OctahedronPolygon::contains(const Vec3d& p) const
{ {
if (sides[getSideNumber(p)].isEmpty()) if (sides[getSideNumber(p)].isEmpty())
return false; return false;
for (int i=0;i<fillCachedVertexArray.vertex.size()/3;++i) for (int i=0;i<fillCachedVertexArray.size()/3;++i)
{ {
if (sideHalfSpaceContains(fillCachedVertexArray.vertex.at(i* if (sideHalfSpaceContains(fillCachedVertexArray.at(i*3+1), f
3+1), fillCachedVertexArray.vertex.at(i*3), p) && illCachedVertexArray.at(i*3), p) &&
sideHalfSpaceContains(fillCachedVertexArray.vertex.a sideHalfSpaceContains(fillCachedVertexArray.at(i*3+2
t(i*3+2), fillCachedVertexArray.vertex.at(i*3+1), p) && ), fillCachedVertexArray.at(i*3+1), p) &&
sideHalfSpaceContains(fillCachedVertexArray.vertex.a sideHalfSpaceContains(fillCachedVertexArray.at(i*3),
t(i*3), fillCachedVertexArray.vertex.at(i*3+2), p)) fillCachedVertexArray.at(i*3+2), p))
return true; return true;
} }
return false; return false;
} }
bool OctahedronPolygon::isEmpty() const bool OctahedronPolygon::isEmpty() const
{ {
return sides[0].isEmpty() && sides[1].isEmpty() && sides[2].isEmpty( ) && sides[3].isEmpty() && return sides[0].isEmpty() && sides[1].isEmpty() && sides[2].isEmpty( ) && sides[3].isEmpty() &&
sides[4].isEmpty() && sides[5].isEmpty() && sides[6] .isEmpty() && sides[7].isEmpty(); sides[4].isEmpty() && sides[5].isEmpty() && sides[6] .isEmpty() && sides[7].isEmpty();
} }
skipping to change at line 807 skipping to change at line 806
// qDebug() << onLine << inputContour.toJSON(); // qDebug() << onLine << inputContour.toJSON();
// if (!result[0].isEmpty()) // if (!result[0].isEmpty())
// qDebug() << result[0].at(0).toJSON(); // qDebug() << result[0].at(0).toJSON();
// if (!result[1].isEmpty()) // if (!result[1].isEmpty())
// qDebug() << result[1].at(0).toJSON(); // qDebug() << result[1].at(0).toJSON();
} }
void OctahedronPolygon::computeBoundingCap() void OctahedronPolygon::computeBoundingCap()
{ {
const QVector<Vec3d>& trianglesArray = outlineCachedVertexArray.vert ex; const QVector<Vec3d>& trianglesArray = outlineCachedVertexArray;
if (trianglesArray.isEmpty()) if (trianglesArray.isEmpty())
{ {
capN.set(1,0,0); capN.set(1,0,0);
capD = 2.; capD = 2.;
return; return;
} }
// This is a quite crapy algorithm // This is a quite crapy algorithm
capN.set(0,0,0); capN.set(0,0,0);
foreach (const Vec3d& v, trianglesArray) foreach (const Vec3d& v, trianglesArray)
capN+=v; capN+=v;
 End of changes. 18 change blocks. 
45 lines changed or deleted 42 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/