Stellarium 0.12.0
Home · All Namespaces · All Classes · Functions · Coding Style · Scripting · Plugins · Renderer · File Structure

StelSphereGeometry.hpp

Go to the documentation of this file.
00001 /*
00002  * Stellarium
00003  * Copyright (C) 2009 Fabien Chereau
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 2
00008  * of the License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335, USA.
00018  */
00019 
00020 #ifndef _STELSPHEREGEOMETRY_HPP_
00021 #define _STELSPHEREGEOMETRY_HPP_
00022 
00023 #include <QDebug>
00024 #include <QSharedPointer>
00025 #include <QVariant>
00026 #include <QVarLengthArray>
00027 #include <QVector>
00028 
00029 #include "OctahedronPolygon.hpp"
00030 #include "renderer/StelVertexBuffer.hpp"
00031 #include "Triplet.hpp"
00032 #include "VecMath.hpp"
00033 
00034 class SphericalRegion;
00035 class SphericalPolygon;
00036 class SphericalConvexPolygon;
00037 class SphericalCap;
00038 class SphericalPoint;
00039 class AllSkySphericalRegion;
00040 class EmptySphericalRegion;
00041 
00042 
00045 
00048 class SphericalRegionP : public QSharedPointer<SphericalRegion>
00049 {
00050 public:
00051     // Override the constructors of QSharedPointer
00052     SphericalRegionP() {;}
00053     SphericalRegionP(SphericalRegion* ptr) : QSharedPointer<SphericalRegion>(ptr) {;}
00054     template <class Deleter> SphericalRegionP(SphericalRegion* ptr, Deleter deleter) : QSharedPointer<SphericalRegion>(ptr, deleter) {;}
00055     SphericalRegionP(const SphericalRegionP& other) : QSharedPointer<SphericalRegion>(other) {;}
00056     SphericalRegionP(const QWeakPointer<SphericalRegion>& other) : QSharedPointer<SphericalRegion>(other) {;}
00057 
00096     static SphericalRegionP loadFromJson(QIODevice* in);
00097 
00100     static SphericalRegionP loadFromJson(const QByteArray& a);
00101 
00104     static SphericalRegionP loadFromQVariant(const QVariantMap& map);
00105     // It can only be a pure shape definition, without texture coords
00106     static SphericalRegionP loadFromQVariant(const QVariantList& list);
00107 
00109     static void serializeToJson(const QVariant& jsonObject, QIODevice* output, int indentLevel=0);
00110 
00112     static int metaTypeId;
00113 
00114 private:
00115 
00117     static int initialize();
00118 };
00119 
00120 // Allow to use SphericalRegionP with the Qt MetaType system.
00121 Q_DECLARE_METATYPE(SphericalRegionP);
00122 
00124 QDataStream& operator<<(QDataStream& out, const SphericalRegionP& region);
00126 QDataStream& operator>>(QDataStream& in, SphericalRegionP& region);
00127 
00132 class SphericalRegion
00133 {
00134 public:
00136     enum SphericalRegionType
00137     {
00138         Point = 0,
00139         Cap = 1,
00140         AllSky = 2,
00141         Polygon = 3,
00142         ConvexPolygon = 4,
00143         Empty = 5,
00144         Invalid = 6
00145     };
00146 
00169     struct DrawParams
00170     {
00177         DrawParams(class StelProjector* projector)
00178             : projector_(projector)
00179             , clippingCap_(NULL)
00180             , subdivide_(true)
00181             , maxSqDistortion_(5.0)
00182         {}
00183 
00192         bool operator != (const DrawParams& rhs) const 
00193         {
00194             // Projector is ignored, as even if the pointer points to the same object, 
00195             // the objects' state might have changed, making comparison useless. 
00196             // Instead, we only cache in cases when projector is not used used outside 
00197             // Renderer (i.e. not affecting vertex buffers that get cached) or NULL.
00198 
00199             // Clipping caps are only considered equal when NULL (which is the 
00200             // most common case, anyway). There is no opportunity for special handling
00201             // like projectors, since, when not NULL, clipping caps are always used 
00202             // in vertex buffer generation.
00203 
00204             return (clippingCap_ == NULL && rhs.clippingCap_ == NULL) ||
00205                    subdivide_ != rhs.subdivide_   ||
00206                    //Fuzzy compare might be better here
00207                    maxSqDistortion_ != rhs.maxSqDistortion_;
00208         }
00209 
00211         DrawParams& clippingCap(const SphericalCap* clippingCap)
00212         {
00213             clippingCap_ = clippingCap;
00214             return *this;
00215         }
00216 
00222         DrawParams& doNotSubdivide()
00223         {
00224             subdivide_ = false;
00225             return *this;
00226         }
00227 
00229         DrawParams& maxSqDistortion(const double maxSqDistortion)
00230         {
00231             maxSqDistortion_ = maxSqDistortion;
00232             return *this;
00233         }
00234 
00236         class StelProjector* projector_;
00237 
00239         const SphericalCap* clippingCap_;
00240 
00242         bool subdivide_;
00243 
00245         double maxSqDistortion_;
00246     };
00247 
00249     struct PlainVertex
00250     {
00251         Vec3f position;
00252         PlainVertex(const Vec3f& position) : position(position){}
00253         PlainVertex(const Vec3d& pos) : position(pos[0], pos[1], pos[2]) {}
00254         VERTEX_ATTRIBUTES(Vec3f Position)
00255     };
00256 
00258     struct TexturedVertex
00259     {
00260         Vec3f position;
00261         Vec2f texCoord;
00262         TexturedVertex(const Vec3f& position, const Vec2f& texCoord)
00263             : position(position) , texCoord(texCoord) {}
00264         TexturedVertex(const Vec3d& pos, const Vec2f& texCoord)
00265             : position(pos[0], pos[1], pos[2]) , texCoord(texCoord) {}
00266         VERTEX_ATTRIBUTES(Vec3f Position, Vec2f TexCoord)
00267     };
00268 
00270     SphericalRegion()
00271         : fillPlainVertexBuffer(NULL)
00272         , previousFillDrawParams(NULL)
00273     {
00274         // Make sure previousFillDrawParams is invalid at start, so it gets replaced 
00275         // at first drawFill() call.
00276         previousFillDrawParams.maxSqDistortion_ = -42.0f;
00277     }
00278 
00280     virtual ~SphericalRegion() 
00281     {
00282         if(NULL != fillPlainVertexBuffer)
00283         {
00284             delete fillPlainVertexBuffer;
00285         }
00286     }
00287 
00288     virtual SphericalRegionType getType() const = 0;
00289 
00292     virtual OctahedronPolygon getOctahedronPolygon() const =0;
00293 
00295     virtual double getArea() const {return getOctahedronPolygon().getArea();}
00296 
00298     virtual bool isEmpty() const {return getOctahedronPolygon().isEmpty();}
00299 
00301     virtual Vec3d getPointInside() const {return getOctahedronPolygon().getPointInside();}
00302 
00304     virtual QVector<SphericalCap> getBoundingSphericalCaps() const;
00305 
00308     virtual SphericalCap getBoundingCap() const;
00309 
00316     virtual SphericalRegionP getEnlarged(double margin) const;
00317 
00319     virtual const QVector<Vec3d>& getFillVertexPositions() const
00320     {
00321         return getOctahedronPolygon().fillVertices();
00322     }
00323 
00326     virtual PrimitiveType getFillPrimitiveType() const 
00327     {
00328         return PrimitiveType_Triangles;
00329     }
00330 
00333     virtual const QVector<Vec3d>& getOutlineVertexPositions() const 
00334     {
00335         // This is a workaround around a compiler bug with Clang (as of Clang 3.2).
00336         // Returning the reference directly results in an uninitialized
00337         // reference which breaks calling code.
00338         const QVector<Vec3d>& result(getOctahedronPolygon().outlineVertices());
00339         return result;
00340     }
00341 
00344     virtual PrimitiveType getOutlinePrimitiveType() const
00345     {
00346         return PrimitiveType_Lines;
00347     }
00348 
00351     virtual QVector<QVector<Vec3d > > getSimplifiedContours() const;
00352     
00354     virtual QVariantList toQVariant() const = 0;
00355 
00357     virtual void serialize(QDataStream& out) const = 0;
00358 
00361     QByteArray toJSON() const;
00362 
00365     bool contains(const SphericalRegion* r) const;
00366     bool contains(const SphericalRegionP r) const {return contains(r.data());}
00367     virtual bool contains(const Vec3d& p) const {return getOctahedronPolygon().contains(p);}
00368     virtual bool contains(const SphericalPolygon& r) const;
00369     virtual bool contains(const SphericalConvexPolygon& r) const;
00370     virtual bool contains(const SphericalCap& r) const;
00371     virtual bool contains(const SphericalPoint& r) const;
00372     virtual bool contains(const AllSkySphericalRegion& r) const;
00373     bool contains(const EmptySphericalRegion&) const {return false;}
00374 
00377     bool intersects(const SphericalRegion* r) const;
00378     bool intersects(const SphericalRegionP r) const {return intersects(r.data());}
00379     bool intersects(const Vec3d& p) const {return contains(p);}
00380     virtual bool intersects(const SphericalPolygon& r) const;
00381     virtual bool intersects(const SphericalConvexPolygon& r) const;
00382     virtual bool intersects(const SphericalCap& r) const;
00383     virtual bool intersects(const SphericalPoint& r) const;
00384     virtual bool intersects(const AllSkySphericalRegion& r) const;
00385     bool intersects(const EmptySphericalRegion&) const {return false;}
00386 
00389     SphericalRegionP getIntersection(const SphericalRegion* r) const;
00390     SphericalRegionP getIntersection(const SphericalRegionP r) const {return getIntersection(r.data());}
00391     virtual SphericalRegionP getIntersection(const SphericalPolygon& r) const;
00392     virtual SphericalRegionP getIntersection(const SphericalConvexPolygon& r) const;
00393     virtual SphericalRegionP getIntersection(const SphericalCap& r) const;
00394     virtual SphericalRegionP getIntersection(const SphericalPoint& r) const;
00395     virtual SphericalRegionP getIntersection(const AllSkySphericalRegion& r) const;
00396     SphericalRegionP getIntersection(const EmptySphericalRegion& r) const;
00397 
00400     SphericalRegionP getUnion(const SphericalRegion* r) const;
00401     SphericalRegionP getUnion(const SphericalRegionP r) const {return getUnion(r.data());}
00402     virtual SphericalRegionP getUnion(const SphericalPolygon& r) const;
00403     virtual SphericalRegionP getUnion(const SphericalConvexPolygon& r) const;
00404     virtual SphericalRegionP getUnion(const SphericalCap& r) const;
00405     virtual SphericalRegionP getUnion(const SphericalPoint& r) const;
00406     SphericalRegionP getUnion(const AllSkySphericalRegion& r) const;
00407     virtual SphericalRegionP getUnion(const EmptySphericalRegion& r) const;
00408 
00411     SphericalRegionP getSubtraction(const SphericalRegion* r) const;
00412     SphericalRegionP getSubtraction(const SphericalRegionP r) const {return getSubtraction(r.data());}
00413     virtual SphericalRegionP getSubtraction(const SphericalPolygon& r) const;
00414     virtual SphericalRegionP getSubtraction(const SphericalConvexPolygon& r) const;
00415     virtual SphericalRegionP getSubtraction(const SphericalCap& r) const;
00416     virtual SphericalRegionP getSubtraction(const SphericalPoint& r) const;
00417     SphericalRegionP getSubtraction(const AllSkySphericalRegion& r) const;
00418     virtual SphericalRegionP getSubtraction(const EmptySphericalRegion& r) const;
00419 
00426     virtual void drawFill(class StelRenderer* renderer, const DrawParams& params);
00427 
00435     virtual void drawOutline(class StelRenderer* renderer, const DrawParams& params);
00436 
00437 protected:
00439     StelVertexBuffer<PlainVertex>* fillPlainVertexBuffer;
00440 
00445     bool useProjector;
00446 
00457     virtual void updateFillVertexBuffer(class StelRenderer* renderer, const DrawParams& params, bool handleDiscontinuity);
00458 
00465     virtual void drawFillVertexBuffer(class StelRenderer* renderer, class StelProjector* projector);
00466 
00472     virtual bool needToUpdateFillVertexBuffers() const
00473     {
00474         // Can't determine whether we can cache anything - 
00475         // we'd need to know if polygon returned by getOctahedronPolygon has changed,
00476         // but since getOctahedronPolygon returns by value, not reference,
00477         // it returns a new octahedronPolygon every time.
00478         //
00479         // If it was by reference, _and_ guaranteed to always point to the same polygon,
00480         // we might store a flag in the polygon determining if its vertex array has 
00481         // changed, and use that for caching.
00482         return true;
00483     }
00484 
00486     virtual void fillVertexBuffersUpdated() {}
00487 
00488 private:
00490     DrawParams previousFillDrawParams;
00491 
00492     bool containsDefault(const SphericalRegion* r) const;
00493     bool intersectsDefault(const SphericalRegion* r) const;
00494     SphericalRegionP getIntersectionDefault(const SphericalRegion* r) const;
00495     SphericalRegionP getUnionDefault(const SphericalRegion* r) const;
00496     SphericalRegionP getSubtractionDefault(const SphericalRegion* r) const;
00497 };
00498 
00499 
00504 class SphericalCap : public SphericalRegion
00505 {
00506 public:
00508     SphericalCap() : d(0) {;}
00509 
00511     SphericalCap(double x, double y, double z) : n(x,y,z), d(0) {;}
00512 
00516     SphericalCap(const Vec3d& an, double ar) : n(an), d(ar) {Q_ASSERT(d==0 || std::fabs(n.lengthSquared()-1.)<0.0000001);}
00517 
00519     SphericalCap(const SphericalCap& other) : SphericalRegion(), n(other.n), d(other.d) {;}
00520 
00521     virtual SphericalRegionType getType() const {return SphericalRegion::Cap;}
00522     virtual OctahedronPolygon getOctahedronPolygon() const;
00523 
00525     virtual double getArea() const {return 2.*M_PI*(1.-d);}
00526 
00528     virtual bool isEmpty() const {return d>=1.;}
00529 
00531     virtual Vec3d getPointInside() const {return n;}
00532 
00534     virtual SphericalCap getBoundingCap() const {return *this;}
00535 
00536     // Contain and intersect    
00537     bool contains(const Vec3d &v) const 
00538     {
00539         Q_ASSERT(d==0 || std::fabs(v.lengthSquared()-1.)<0.00000021);
00540         return (v*n>=d);
00541     }
00542     virtual bool contains(const SphericalConvexPolygon& r) const;
00543     virtual bool contains(const SphericalCap& h) const
00544     {
00545         const double a = n*h.n-d*h.d;
00546         return d<=h.d && ( a>=1. || (a>=0. && a*a >= (1.-d*d)*(1.-h.d*h.d)));
00547     }
00548     virtual bool contains(const AllSkySphericalRegion&) const {return d<=-1;}
00549     virtual bool intersects(const SphericalPolygon& r) const;
00550     virtual bool intersects(const SphericalConvexPolygon& r) const;
00554     virtual bool intersects(const SphericalCap& h) const
00555     {
00556         const double a = d*h.d - n*h.n;
00557         return d+h.d<=0. || a<=0. || (a<=1. && a*a <= (1.-d*d)*(1.-h.d*h.d));
00558     }
00559     virtual bool intersects(const AllSkySphericalRegion&) const {return d<=1.;}
00560 
00564     virtual QVariantList toQVariant() const;
00565 
00566     virtual void serialize(QDataStream& out) const {out << n << d;}
00567 
00569     // Methods specific to SphericalCap
00570 
00572     double getRadius() const {return std::acos(d);}
00573 
00578     inline bool intersectsHalfSpace(double hn0, double hn1, double hn2) const
00579     {
00580         const double a = n[0]*hn0+n[1]*hn1+n[2]*hn2;
00581         return d<=0. || a<=0. || (a<=1. && a*a <= (1.-d*d));
00582     }
00583 
00586     bool clipGreatCircle(Vec3d& v1, Vec3d& v2) const;
00587 
00589     bool operator==(const SphericalCap& other) const {return (n==other.n && d==other.d);}
00590 
00592     QVector<Vec3d> getClosedOutlineContour() const;
00593 
00595     bool intersectsConvexContour(const Vec3d* vertice, int nbVertice) const;
00596 
00598     bool containsTriangle(const Triplet<Vec3d> triangle) const;
00599 
00601     bool intersectsTriangle(const Triplet<Vec3d>& triangle) const;
00602 
00604     static SphericalRegionP deserialize(QDataStream& in);
00605 
00608     static double relativeAreaOverlap(const SphericalCap& c1, const SphericalCap& c2);
00609 
00612     static double relativeDiameterOverlap(const SphericalCap& c1, const SphericalCap& c2);
00613 
00616     static bool intersectionPoints(const SphericalCap& h1, const SphericalCap& h2, Vec3d& p1, Vec3d& p2);
00617 
00619     Vec3d n;
00621     double d;
00622 };
00623 
00627 inline bool sideHalfSpaceContains(const Vec3d& v1, const Vec3d& v2, const Vec3d& p)
00628 {
00629     return (v1[1] * v2[2] - v1[2] * v2[1])*p[0] +
00630             (v1[2] * v2[0] - v1[0] * v2[2])*p[1] +
00631             (v1[0] * v2[1] - v1[1] * v2[0])*p[2]>=-1e-17;
00632 }
00633 
00635 inline bool sideHalfSpaceContains(const Vec3d& v1, const Vec3d& v2, const SphericalCap& h)
00636 {
00637     Vec3d n(v1[1]*v2[2]-v1[2]*v2[1], v2[0]*v1[2]-v2[2]*v1[0], v2[1]*v1[0]-v2[0]*v1[1]);
00638     n.normalize();
00639     const double a = n*h.n;
00640     return 0<=h.d && ( a>=1. || (a>=0. && a*a >= 1.-h.d*h.d));
00641 }
00642 
00644 inline bool sideHalfSpaceIntersects(const Vec3d& v1, const Vec3d& v2, const SphericalCap& h)
00645 {
00646     Vec3d n(v1[1]*v2[2]-v1[2]*v2[1], v2[0]*v1[2]-v2[2]*v1[0], v2[1]*v1[0]-v2[0]*v1[1]);
00647     n.normalize();
00648     return  h.intersectsHalfSpace(n[0], n[1], n[2]);
00649 }
00650 
00653 class SphericalPoint : public SphericalRegion
00654 {
00655 public:
00656     SphericalPoint(const Vec3d& an) : n(an) {Q_ASSERT(std::fabs(1.-n.length())<0.0000001);}
00657     virtual ~SphericalPoint() {;}
00658 
00659     virtual SphericalRegionType getType() const {return SphericalRegion::Point;}
00660     virtual OctahedronPolygon getOctahedronPolygon() const;
00661     virtual double getArea() const {return 0.;}
00662     virtual bool isEmpty() const {return false;}
00663     virtual Vec3d getPointInside() const {return n;}
00664     virtual SphericalCap getBoundingCap() const {return SphericalCap(n, 1);}
00667     virtual QVariantList toQVariant() const;
00668     virtual void serialize(QDataStream& out) const {out << n;}
00669 
00670     // Contain and intersect
00671     virtual bool contains(const Vec3d& p) const {return n==p;}
00672     virtual bool contains(const SphericalPolygon&) const {return false;}
00673     virtual bool contains(const SphericalConvexPolygon&) const {return false;}
00674     virtual bool contains(const SphericalCap&) const {return false;}
00675     virtual bool contains(const SphericalPoint& r) const {return n==r.n;}
00676     virtual bool contains(const AllSkySphericalRegion&) const {return false;}
00677     virtual bool intersects(const SphericalPolygon&) const;
00678     virtual bool intersects(const SphericalConvexPolygon&) const;
00679     virtual bool intersects(const SphericalCap& r) const {return r.contains(n);}
00680     virtual bool intersects(const SphericalPoint& r) const {return n==r.n;}
00681     virtual bool intersects(const AllSkySphericalRegion&) const {return true;}
00682 
00684     static SphericalRegionP deserialize(QDataStream& in);
00685 
00687     Vec3d n;
00688 };
00689 
00692 class AllSkySphericalRegion : public SphericalRegion
00693 {
00694 public:
00695     virtual ~AllSkySphericalRegion() {;}
00696 
00697     virtual SphericalRegionType getType() const {return SphericalRegion::AllSky;}
00698     virtual OctahedronPolygon getOctahedronPolygon() const 
00699     {
00700         return OctahedronPolygon::getAllSkyOctahedronPolygon();
00701     }
00702     virtual double getArea() const {return 4.*M_PI;}
00703     virtual bool isEmpty() const {return false;}
00704     virtual Vec3d getPointInside() const {return Vec3d(1,0,0);}
00705     virtual SphericalCap getBoundingCap() const {return SphericalCap(Vec3d(1,0,0), -2);}
00708     virtual QVariantList toQVariant() const;
00709     virtual void serialize(QDataStream&) const {;}
00710 
00711     // Contain and intersect
00712     virtual bool contains(const Vec3d&) const {return true;}
00713     virtual bool contains(const SphericalPolygon&) const {return true;}
00714     virtual bool contains(const SphericalConvexPolygon&) const {return true;}
00715     virtual bool contains(const SphericalCap&) const {return true;}
00716     virtual bool contains(const SphericalPoint&) const {return true;}
00717     virtual bool contains(const AllSkySphericalRegion&) const {return true;}
00718     virtual bool intersects(const SphericalPolygon&) const {return true;}
00719     virtual bool intersects(const SphericalConvexPolygon&) const {return true;}
00720     virtual bool intersects(const SphericalCap&) const {return true;}
00721     virtual bool intersects(const SphericalPoint&) const {return true;}
00722     virtual bool intersects(const AllSkySphericalRegion&) const {return true;}
00723 
00724     static const SphericalRegionP staticInstance;
00725 };
00726 
00729 class EmptySphericalRegion : public SphericalRegion
00730 {
00731 public:
00732     // Avoid name hiding when overloading the virtual methods.
00733     using SphericalRegion::intersects;
00734     using SphericalRegion::contains;
00735     using SphericalRegion::getIntersection;
00736     using SphericalRegion::getUnion;
00737     using SphericalRegion::getSubtraction;
00738 
00739     EmptySphericalRegion() {;}
00740     virtual ~EmptySphericalRegion() {;}
00741 
00742     virtual SphericalRegionType getType() const {return SphericalRegion::Empty;}
00743     virtual OctahedronPolygon getOctahedronPolygon() const 
00744     {
00745         return OctahedronPolygon::getEmptyOctahedronPolygon();
00746     }
00747     virtual double getArea() const {return 0.;}
00748     virtual bool isEmpty() const {return true;}
00749     virtual Vec3d getPointInside() const {return Vec3d(1,0,0);}
00750     virtual SphericalCap getBoundingCap() const {return SphericalCap(Vec3d(1,0,0), 2);}
00753     virtual QVariantList toQVariant() const;
00754     virtual void serialize(QDataStream&) const {;}
00755 
00756     // Contain and intersect
00757     virtual bool contains(const Vec3d&) const {return false;}
00758     virtual bool contains(const SphericalPolygon&) const {return false;}
00759     virtual bool contains(const SphericalConvexPolygon&) const {return false;}
00760     virtual bool contains(const SphericalCap&) const {return false;}
00761     virtual bool contains(const SphericalPoint&) const {return false;}
00762     virtual bool contains(const AllSkySphericalRegion&) const {return false;}
00763     virtual bool intersects(const SphericalPolygon&) const {return false;}
00764     virtual bool intersects(const SphericalConvexPolygon&) const {return false;}
00765     virtual bool intersects(const SphericalCap&) const {return false;}
00766     virtual bool intersects(const SphericalPoint&) const {return false;}
00767     virtual bool intersects(const AllSkySphericalRegion&) const {return false;}
00768 
00769     static const SphericalRegionP staticInstance;
00770 };
00771 
00772 
00776 class SphericalPolygon : public SphericalRegion
00777 {
00778 public:
00779     // Avoid name hiding when overloading the virtual methods.
00780     using SphericalRegion::intersects;
00781     using SphericalRegion::contains;
00782     using SphericalRegion::getIntersection;
00783     using SphericalRegion::getUnion;
00784     using SphericalRegion::getSubtraction;
00785 
00786     SphericalPolygon() {;}
00788     SphericalPolygon(const QVector<QVector<Vec3d> >& contours) : octahedronPolygon(contours) {;}
00790     SphericalPolygon(const QVector<Vec3d>& contour) : octahedronPolygon(contour) {;}
00791     SphericalPolygon(const OctahedronPolygon& octContour) : octahedronPolygon(octContour) {;}
00792     SphericalPolygon(const QList<OctahedronPolygon>& octContours) : octahedronPolygon(octContours) {;}
00793 
00794     virtual SphericalRegionType getType() const {return SphericalRegion::Polygon;}
00795     virtual OctahedronPolygon getOctahedronPolygon() const 
00796     {
00797         return octahedronPolygon;
00798     }
00799 
00804     virtual QVariantList toQVariant() const;
00805     virtual void serialize(QDataStream& out) const;
00806 
00807     virtual SphericalCap getBoundingCap() const;
00808 
00809     virtual bool contains(const Vec3d& p) const {return octahedronPolygon.contains(p);}
00810     virtual bool contains(const SphericalPolygon& r) const {return octahedronPolygon.contains(r.octahedronPolygon);}
00811     virtual bool contains(const SphericalConvexPolygon& r) const;
00812     virtual bool contains(const SphericalCap& r) const {return octahedronPolygon.contains(r.getOctahedronPolygon());}
00813     virtual bool contains(const SphericalPoint& r) const {return octahedronPolygon.contains(r.n);}
00814     virtual bool contains(const AllSkySphericalRegion& r) const {return octahedronPolygon.contains(r.getOctahedronPolygon());}
00815 
00816     virtual bool intersects(const SphericalPolygon& r) const {return octahedronPolygon.intersects(r.octahedronPolygon);}
00817     virtual bool intersects(const SphericalConvexPolygon& r) const;
00818     virtual bool intersects(const SphericalCap& r) const {return r.intersects(*this);}
00819     virtual bool intersects(const SphericalPoint& r) const {return octahedronPolygon.contains(r.n);}
00820     virtual bool intersects(const AllSkySphericalRegion&) const {return !isEmpty();}
00821 
00822     virtual SphericalRegionP getIntersection(const SphericalPoint& r) const {return contains(r.n) ? SphericalRegionP(new SphericalPoint(r)) : EmptySphericalRegion::staticInstance;}
00823     virtual SphericalRegionP getIntersection(const AllSkySphericalRegion& ) const {return SphericalRegionP(new SphericalPolygon(octahedronPolygon));}
00824 
00825     virtual SphericalRegionP getUnion(const SphericalPoint&) const {return SphericalRegionP(new SphericalPolygon(octahedronPolygon));}
00826     virtual SphericalRegionP getUnion(const EmptySphericalRegion&) const {return SphericalRegionP(new SphericalPolygon(octahedronPolygon));}
00827 
00828     virtual SphericalRegionP getSubtraction(const SphericalPoint&) const {return SphericalRegionP(new SphericalPolygon(octahedronPolygon));}
00829     virtual SphericalRegionP getSubtraction(const EmptySphericalRegion&) const {return SphericalRegionP(new SphericalPolygon(octahedronPolygon));}
00830 
00832     // Methods specific to SphericalPolygon
00836     void setContours(const QVector<QVector<Vec3d> >& contours) 
00837     {
00838         octahedronPolygon = OctahedronPolygon(contours);
00839     }
00840 
00843     void setContour(const QVector<Vec3d>& contour) 
00844     {
00845         octahedronPolygon = OctahedronPolygon(contour);
00846     }
00847 
00849     QVector<QVector<Vec3d> > getClosedOutlineContours() const {Q_ASSERT(0); return QVector<QVector<Vec3d> >();}
00850 
00852     static SphericalRegionP deserialize(QDataStream& in);
00853 
00855     static SphericalRegionP multiUnion(const QList<SphericalRegionP>& regions, bool optimizeByPreGrouping=false);
00856     
00858     static SphericalRegionP multiIntersection(const QList<SphericalRegionP>& regions);
00859 
00860 private:
00861     OctahedronPolygon octahedronPolygon;
00862 };
00863 
00864 
00867 class SphericalConvexPolygon : public SphericalRegion
00868 {
00869 public:
00870     // Avoid name hiding when overloading the virtual methods.
00871     using SphericalRegion::intersects;
00872     using SphericalRegion::contains;
00873 
00875     SphericalConvexPolygon() {;}
00876 
00878     SphericalConvexPolygon(const QVector<QVector<Vec3d> >& contours)
00879         : fillVertexBufferNeedsUpdate(true)
00880     {
00881         Q_ASSERT(contours.size()==1); 
00882         setContour(contours.at(0));
00883     }
00884 
00886     SphericalConvexPolygon(const QVector<Vec3d>& contour) 
00887         : fillVertexBufferNeedsUpdate(true)
00888     {
00889         setContour(contour);
00890     }
00891 
00893     SphericalConvexPolygon(const Vec3d &e0,const Vec3d &e1,const Vec3d &e2) 
00894         : fillVertexBufferNeedsUpdate(true)
00895     {
00896         contour << e0 << e1 << e2; updateBoundingCap();
00897     }
00898 
00900     SphericalConvexPolygon(const Vec3d &e0,const Vec3d &e1,const Vec3d &e2, const Vec3d &e3)  
00901         : fillVertexBufferNeedsUpdate(true)
00902     {
00903         contour << e0 << e1 << e2 << e3; updateBoundingCap();
00904     }
00905 
00906     virtual SphericalRegionType getType() const {return SphericalRegion::ConvexPolygon;}
00907 
00908     virtual OctahedronPolygon getOctahedronPolygon() const 
00909     {
00910         return OctahedronPolygon(contour);
00911     }
00912 
00913     virtual const QVector<Vec3d>& getFillVertexPositions() const
00914     {
00915         return contour;
00916     }
00917 
00918     virtual PrimitiveType getFillPrimitiveType() const 
00919     {
00920         return PrimitiveType_TriangleFan;
00921     }
00922 
00923     virtual const QVector<Vec3d>& getOutlineVertexPositions() const 
00924     {
00925         return contour;
00926     }
00927 
00928     virtual PrimitiveType getOutlinePrimitiveType() const
00929     {
00930         return PrimitiveType_LineLoop;
00931     }
00932 
00933     virtual double getArea() const;
00934     virtual bool isEmpty() const {return contour.isEmpty();}
00935     virtual Vec3d getPointInside() const;
00936     virtual SphericalCap getBoundingCap() const {return cachedBoundingCap;}
00937     QVector<SphericalCap> getBoundingSphericalCaps() const;
00942     virtual QVariantList toQVariant() const;
00943     virtual void serialize(QDataStream& out) const {out << contour;}
00944 
00945     // Contain and intersect
00946     virtual bool contains(const Vec3d& p) const;
00947     virtual bool contains(const SphericalPolygon& r) const;
00948     virtual bool contains(const SphericalConvexPolygon& r) const;
00949     virtual bool contains(const SphericalCap& r) const;
00950     virtual bool contains(const SphericalPoint& r) const {return contains(r.n);}
00951     virtual bool contains(const AllSkySphericalRegion&) const {return false;}
00952     virtual bool intersects(const SphericalCap& r) const {if (!cachedBoundingCap.intersects(r)) return false; return r.intersects(*this);}
00953     virtual bool intersects(const SphericalPolygon& r) const;
00954     virtual bool intersects(const SphericalConvexPolygon& r) const;
00955     virtual bool intersects(const SphericalPoint& r) const {return contains(r.n);}
00956     virtual bool intersects(const AllSkySphericalRegion&) const {return true;}
00957 
00959 //  virtual SphericalRegionP getIntersection(const SphericalPolygon& r) const;
00960 //  virtual SphericalRegionP getIntersection(const SphericalConvexPolygon& r) const;
00961 //  virtual SphericalRegionP getIntersection(const SphericalCap& r) const;
00962 //  virtual SphericalRegionP getIntersection(const SphericalPoint& r) const;
00963 //  virtual SphericalRegionP getIntersection(const AllSkySphericalRegion& r) const;
00964 //  virtual SphericalRegionP getUnion(const SphericalPolygon& r) const;
00965 //  virtual SphericalRegionP getUnion(const SphericalConvexPolygon& r) const;
00966 //  virtual SphericalRegionP getUnion(const SphericalCap& r) const;
00967 //  virtual SphericalRegionP getUnion(const SphericalPoint& r) const;
00968 //  virtual SphericalRegionP getUnion(const EmptySphericalRegion& r) const;
00969 //  virtual SphericalRegionP getSubtraction(const SphericalPolygon& r) const;
00970 //  virtual SphericalRegionP getSubtraction(const SphericalConvexPolygon& r) const;
00971 //  virtual SphericalRegionP getSubtraction(const SphericalCap& r) const;
00972 //  virtual SphericalRegionP getSubtraction(const SphericalPoint& r) const;
00973 //  virtual SphericalRegionP getSubtraction(const EmptySphericalRegion& r) const;
00974 
00976     // Methods specific to SphericalConvexPolygon
00980     void setContour(const QVector<Vec3d>& acontour) 
00981     {
00982         contour = acontour;
00983         fillVertexBufferNeedsUpdate = true;
00984         updateBoundingCap();
00985     }
00986 
00988     const QVector<Vec3d>& getConvexContour() const {return contour;}
00989 
00991     bool checkValid() const;
00992 
00994     static bool checkValidContour(const QVector<Vec3d>& contour);
00995 
00997     static SphericalRegionP deserialize(QDataStream& in);
00998 
00999 protected:
01001     QVector<Vec3d> contour;
01002 
01004     SphericalCap cachedBoundingCap;
01005 
01007     bool fillVertexBufferNeedsUpdate;
01008 
01010     void updateBoundingCap();
01011 
01012     virtual void updateFillVertexBuffer(class StelRenderer* renderer, const DrawParams& params, bool handleDiscontinuity);
01013 
01014     virtual void drawFillVertexBuffer(class StelRenderer* renderer, class StelProjector* projector);
01015 
01016     virtual bool needToUpdateFillVertexBuffers() const
01017     {
01018         return fillVertexBufferNeedsUpdate;
01019     }
01020 
01021     virtual void fillVertexBuffersUpdated()
01022     {
01023         fillVertexBufferNeedsUpdate = false;
01024     }
01025 
01031     static bool areAllPointsOutsideOneSide(const Vec3d* thisContour, int nbThisContour, const Vec3d* points, int nbPoints);
01032 
01034     bool areAllPointsOutsideOneSide(const QVector<Vec3d>& points) const
01035     {
01036         return areAllPointsOutsideOneSide(contour.constData(), contour.size(), points.constData(), points.size());
01037     }
01038 
01039     bool containsConvexContour(const Vec3d* vertice, int nbVertex) const;
01040 };
01041 
01042 
01045 //class SphericalConvexPolygonSet : public SphericalRegion
01046 //{
01047 //public:
01048 //  // Avoid name hiding when overloading the virtual methods.
01049 //  using SphericalRegion::intersects;
01050 //  using SphericalRegion::contains;
01051 //
01052 //  //! Default constructor.
01053 //  SphericalConvexPolygonSet() {;}
01054 //
01055 //  //! Constructor from a list of contours.
01056 //  SphericalConvexPolygonSet(const QVector<QVector<Vec3d> >& contours);
01057 //
01058 //  virtual SphericalRegionType getType() const {return SphericalRegion::ConvexPolygonSet;}
01059 //  virtual OctahedronPolygon getOctahedronPolygon() const;
01060 //  virtual StelVertexArray getFillVertexArray() const;
01061 //  virtual StelVertexArray getOutlineVertexArray() const;
01062 //  virtual double getArea() const;
01063 //  virtual bool isEmpty() const;
01064 //  virtual Vec3d getPointInside() const;
01065 //  virtual SphericalCap getBoundingCap() const {return cachedBoundingCap;}
01066 //  QVector<SphericalCap> getBoundingSphericalCaps() const;
01067 //  //! Serialize the region into a QVariant map matching the JSON format.
01068 //  //! The format is
01069 //  //! @code["CONVEX_POLYGON_SET", [[ra,dec], [ra,dec], [ra,dec], [ra,dec]], [[ra,dec], [ra,dec], [ra,dec], [ra,dec]]]@endcode
01070 //  //! where the coords from a list of closed convex contour, with each points defined by ra dec in degree in the ICRS frame.
01071 //  virtual QVariantList toQVariant() const;
01072 //  virtual void serialize(QDataStream& out) const;
01073 //
01074 //  // Contain and intersect
01075 //  virtual bool contains(const Vec3d& p) const;
01076 //  virtual bool contains(const SphericalPolygon& r) const;
01077 //  virtual bool contains(const SphericalConvexPolygon& r) const;
01078 //  virtual bool contains(const SphericalCap& r) const;
01079 //  virtual bool contains(const SphericalPoint& r) const {return contains(r.n);}
01080 //  virtual bool contains(const AllSkySphericalRegion&) const {return false;}
01081 //  virtual bool intersects(const SphericalCap& r) const {if (!cachedBoundingCap.intersects(r)) return false; return r.intersects(*this);}
01082 //  virtual bool intersects(const SphericalPolygon& r) const;
01083 //  virtual bool intersects(const SphericalConvexPolygon& r) const;
01084 //  virtual bool intersects(const SphericalPoint& r) const {return contains(r.n);}
01085 //  virtual bool intersects(const AllSkySphericalRegion&) const {return true;}
01086 //
01087 //  ////////////////////////////////////////////////////////////////////
01088 //  // Methods specific to SphericalConvexPolygonSet
01089 //  ////////////////////////////////////////////////////////////////////
01090 //  //! Deserialize the region. This method must allow as fast as possible deserialization.
01091 //  static SphericalRegionP deserialize(QDataStream& in);
01092 //
01093 //protected:
01094 //  QVector<SphericalConvexPolygon> contours;
01095 //
01096 //  //! Cache the bounding cap.
01097 //  SphericalCap cachedBoundingCap;
01098 //
01099 //  //! Update the bounding cap from the vertex list.
01100 //  void updateBoundingCap();
01101 //};
01102 
01103 
01106 class SphericalTexturedConvexPolygon : public SphericalConvexPolygon
01107 {
01108 public:
01110     SphericalTexturedConvexPolygon() : fillTexturedVertexBuffer(NULL) 
01111     {
01112         fillVertexBufferNeedsUpdate = true;
01113     }
01114 
01116     SphericalTexturedConvexPolygon(const QVector<Vec3d>& contour, const QVector<Vec2f>& texCoord) 
01117         : fillTexturedVertexBuffer(NULL)
01118     {
01119         setContour(contour, texCoord);
01120         fillVertexBufferNeedsUpdate = true;
01121     }
01122 
01125     SphericalTexturedConvexPolygon(const Vec3d &e0,const Vec3d &e1,const Vec3d &e2, const Vec3d &e3) 
01126         : SphericalConvexPolygon(e0,e1,e2,e3)
01127         , fillTexturedVertexBuffer(NULL)
01128     {
01129         textureCoords << Vec2f(0.f, 0.f) << Vec2f(1.f, 0.f) << Vec2f(1.f, 1.f) << Vec2f(0.f, 1.f);
01130         fillVertexBufferNeedsUpdate = true;
01131     }
01132 
01133     virtual ~SphericalTexturedConvexPolygon()
01134     {
01135         if(NULL != fillTexturedVertexBuffer)
01136         {
01137             delete fillTexturedVertexBuffer;
01138         }
01139     }
01140 
01144     virtual void setContour(const QVector<Vec3d>& acontour, const QVector<Vec2f>& texCoord) 
01145     {
01146         SphericalConvexPolygon::setContour(acontour); 
01147         textureCoords=texCoord;
01148         fillVertexBufferNeedsUpdate = true;
01149     }
01150 
01157     virtual QVariantList toQVariant() const;
01158 
01159     virtual void serialize(QDataStream& out) const {out << contour << textureCoords;}
01160 
01161 protected:
01164     QVector<Vec2f> textureCoords;
01165 
01167     StelVertexBuffer<TexturedVertex>* fillTexturedVertexBuffer;
01168 
01169     virtual void updateFillVertexBuffer(class StelRenderer* renderer, const DrawParams& params, bool handleDiscontinuity);
01170 
01171     virtual void drawFillVertexBuffer(class StelRenderer* renderer, class StelProjector* projector);
01172 };
01173 
01174 
01182 Vec3d greatCircleIntersection(const Vec3d& p1, const Vec3d& p2, const Vec3d& p3, const Vec3d& p4, bool& ok);
01183 
01190 Vec3d greatCircleIntersection(const Vec3d& p1, const Vec3d& p2, const Vec3d& nHalfSpace, bool& ok);
01191 
01192 #endif // _STELSPHEREGEOMETRY_HPP_
01193 
Generated on Thu Jan 31 14:05:41 2013 for Stellarium by  doxygen 1.6.3