Stellarium 0.12.4
StelSphereGeometry.hpp
Go to the documentation of this file.
1 /*
2  * Stellarium
3  * Copyright (C) 2009 Fabien Chereau
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18  */
19 
20 #ifndef _STELSPHEREGEOMETRY_HPP_
21 #define _STELSPHEREGEOMETRY_HPP_
22 
23 #include <QDebug>
24 #include <QSharedPointer>
25 #include <QVariant>
26 #include <QVarLengthArray>
27 #include <QVector>
28 
29 #include "OctahedronPolygon.hpp"
30 #include "renderer/StelVertexBuffer.hpp"
31 #include "Triplet.hpp"
32 #include "VecMath.hpp"
33 
34 class SphericalRegion;
35 class SphericalPolygon;
37 class SphericalCap;
38 class SphericalPoint;
41 
42 
45 
48 class SphericalRegionP : public QSharedPointer<SphericalRegion>
49 {
50 public:
51  // Override the constructors of QSharedPointer
52  SphericalRegionP() {;}
53  SphericalRegionP(SphericalRegion* ptr) : QSharedPointer<SphericalRegion>(ptr) {;}
54  template <class Deleter> SphericalRegionP(SphericalRegion* ptr, Deleter deleter) : QSharedPointer<SphericalRegion>(ptr, deleter) {;}
55  SphericalRegionP(const SphericalRegionP& other) : QSharedPointer<SphericalRegion>(other) {;}
56  SphericalRegionP(const QWeakPointer<SphericalRegion>& other) : QSharedPointer<SphericalRegion>(other) {;}
57 
96  static SphericalRegionP loadFromJson(QIODevice* in);
97 
100  static SphericalRegionP loadFromJson(const QByteArray& a);
101 
104  static SphericalRegionP loadFromQVariant(const QVariantMap& map);
105  // It can only be a pure shape definition, without texture coords
106  static SphericalRegionP loadFromQVariant(const QVariantList& list);
107 
109  static void serializeToJson(const QVariant& jsonObject, QIODevice* output, int indentLevel=0);
110 
112  static int metaTypeId;
113 
114 private:
115 
117  static int initialize();
118 };
119 
120 // Allow to use SphericalRegionP with the Qt MetaType system.
121 Q_DECLARE_METATYPE(SphericalRegionP);
122 
124 QDataStream& operator<<(QDataStream& out, const SphericalRegionP& region);
126 QDataStream& operator>>(QDataStream& in, SphericalRegionP& region);
127 
133 {
134 public:
137  {
138  Point = 0,
139  Cap = 1,
140  AllSky = 2,
141  Polygon = 3,
142  ConvexPolygon = 4,
143  Empty = 5,
144  Invalid = 6
145  };
146 
169  struct DrawParams
170  {
177  DrawParams(class StelProjector* projector)
178  : projector_(projector)
179  , clippingCap_(NULL)
180  , subdivide_(true)
181  , maxSqDistortion_(5.0)
182  {}
183 
192  bool operator != (const DrawParams& rhs) const
193  {
194  // Projector is ignored, as even if the pointer points to the same object,
195  // the objects' state might have changed, making comparison useless.
196  // Instead, we only cache in cases when projector is not used used outside
197  // Renderer (i.e. not affecting vertex buffers that get cached) or NULL.
198 
199  // Clipping caps are only considered equal when NULL (which is the
200  // most common case, anyway). There is no opportunity for special handling
201  // like projectors, since, when not NULL, clipping caps are always used
202  // in vertex buffer generation.
203 
204  return (clippingCap_ == NULL && rhs.clippingCap_ == NULL) ||
205  subdivide_ != rhs.subdivide_ ||
206  //Fuzzy compare might be better here
208  }
209 
212  {
214  return *this;
215  }
216 
223  {
224  subdivide_ = false;
225  return *this;
226  }
227 
230  {
232  return *this;
233  }
234 
237 
240 
243 
246  };
247 
249  struct PlainVertex
250  {
251  Vec3f position;
252  PlainVertex(const Vec3f& position) : position(position){}
253  PlainVertex(const Vec3d& pos) : position(pos[0], pos[1], pos[2]) {}
254  VERTEX_ATTRIBUTES(Vec3f Position)
255  };
256 
259  {
260  Vec3f position;
261  Vec2f texCoord;
262  TexturedVertex(const Vec3f& position, const Vec2f& texCoord)
263  : position(position) , texCoord(texCoord) {}
264  TexturedVertex(const Vec3d& pos, const Vec2f& texCoord)
265  : position(pos[0], pos[1], pos[2]) , texCoord(texCoord) {}
266  VERTEX_ATTRIBUTES(Vec3f Position, Vec2f TexCoord)
267  };
268 
271  : fillPlainVertexBuffer(NULL)
272  , previousFillDrawParams(NULL)
273  {
274  // Make sure previousFillDrawParams is invalid at start, so it gets replaced
275  // at first drawFill() call.
276  previousFillDrawParams.maxSqDistortion_ = -42.0f;
277  }
278 
280  virtual ~SphericalRegion()
281  {
282  if(NULL != fillPlainVertexBuffer)
283  {
284  delete fillPlainVertexBuffer;
285  }
286  }
287 
288  virtual SphericalRegionType getType() const = 0;
289 
292  virtual OctahedronPolygon getOctahedronPolygon() const =0;
293 
295  virtual double getArea() const {return getOctahedronPolygon().getArea();}
296 
298  virtual bool isEmpty() const {return getOctahedronPolygon().isEmpty();}
299 
301  virtual Vec3d getPointInside() const {return getOctahedronPolygon().getPointInside();}
302 
304  virtual QVector<SphericalCap> getBoundingSphericalCaps() const;
305 
308  virtual SphericalCap getBoundingCap() const;
309 
316  virtual SphericalRegionP getEnlarged(double margin) const;
317 
319  virtual const QVector<Vec3d>& getFillVertexPositions() const
320  {
322  }
323 
326  virtual PrimitiveType getFillPrimitiveType() const
327  {
328  return PrimitiveType_Triangles;
329  }
330 
333  virtual const QVector<Vec3d>& getOutlineVertexPositions() const
334  {
335  // This is a workaround around a compiler bug with Clang (as of Clang 3.2).
336  // Returning the reference directly results in an uninitialized
337  // reference which breaks calling code.
338  const QVector<Vec3d>& result(getOctahedronPolygon().outlineVertices());
339  return result;
340  }
341 
344  virtual PrimitiveType getOutlinePrimitiveType() const
345  {
346  return PrimitiveType_Lines;
347  }
348 
351  virtual QVector<QVector<Vec3d > > getSimplifiedContours() const;
352 
354  virtual QVariantList toQVariant() const = 0;
355 
357  virtual void serialize(QDataStream& out) const = 0;
358 
361  QByteArray toJSON() const;
362 
365  bool contains(const SphericalRegion* r) const;
366  bool contains(const SphericalRegionP r) const {return contains(r.data());}
367  virtual bool contains(const Vec3d& p) const {return getOctahedronPolygon().contains(p);}
368  virtual bool contains(const SphericalPolygon& r) const;
369  virtual bool contains(const SphericalConvexPolygon& r) const;
370  virtual bool contains(const SphericalCap& r) const;
371  virtual bool contains(const SphericalPoint& r) const;
372  virtual bool contains(const AllSkySphericalRegion& r) const;
373  bool contains(const EmptySphericalRegion&) const {return false;}
374 
377  bool intersects(const SphericalRegion* r) const;
378  bool intersects(const SphericalRegionP r) const {return intersects(r.data());}
379  bool intersects(const Vec3d& p) const {return contains(p);}
380  virtual bool intersects(const SphericalPolygon& r) const;
381  virtual bool intersects(const SphericalConvexPolygon& r) const;
382  virtual bool intersects(const SphericalCap& r) const;
383  virtual bool intersects(const SphericalPoint& r) const;
384  virtual bool intersects(const AllSkySphericalRegion& r) const;
385  bool intersects(const EmptySphericalRegion&) const {return false;}
386 
390  SphericalRegionP getIntersection(const SphericalRegionP r) const {return getIntersection(r.data());}
391  virtual SphericalRegionP getIntersection(const SphericalPolygon& r) const;
393  virtual SphericalRegionP getIntersection(const SphericalCap& r) const;
394  virtual SphericalRegionP getIntersection(const SphericalPoint& r) const;
397 
400  SphericalRegionP getUnion(const SphericalRegion* r) const;
401  SphericalRegionP getUnion(const SphericalRegionP r) const {return getUnion(r.data());}
402  virtual SphericalRegionP getUnion(const SphericalPolygon& r) const;
403  virtual SphericalRegionP getUnion(const SphericalConvexPolygon& r) const;
404  virtual SphericalRegionP getUnion(const SphericalCap& r) const;
405  virtual SphericalRegionP getUnion(const SphericalPoint& r) const;
407  virtual SphericalRegionP getUnion(const EmptySphericalRegion& r) const;
408 
412  SphericalRegionP getSubtraction(const SphericalRegionP r) const {return getSubtraction(r.data());}
413  virtual SphericalRegionP getSubtraction(const SphericalPolygon& r) const;
415  virtual SphericalRegionP getSubtraction(const SphericalCap& r) const;
416  virtual SphericalRegionP getSubtraction(const SphericalPoint& r) const;
418  virtual SphericalRegionP getSubtraction(const EmptySphericalRegion& r) const;
419 
426  virtual void drawFill(class StelRenderer* renderer, const DrawParams& params);
427 
435  virtual void drawOutline(class StelRenderer* renderer, const DrawParams& params);
436 
437 protected:
440 
446 
457  virtual void updateFillVertexBuffer(class StelRenderer* renderer, const DrawParams& params, bool handleDiscontinuity);
458 
465  virtual void drawFillVertexBuffer(class StelRenderer* renderer, class StelProjector* projector);
466 
472  virtual bool needToUpdateFillVertexBuffers() const
473  {
474  // Can't determine whether we can cache anything -
475  // we'd need to know if polygon returned by getOctahedronPolygon has changed,
476  // but since getOctahedronPolygon returns by value, not reference,
477  // it returns a new octahedronPolygon every time.
478  //
479  // If it was by reference, _and_ guaranteed to always point to the same polygon,
480  // we might store a flag in the polygon determining if its vertex array has
481  // changed, and use that for caching.
482  return true;
483  }
484 
486  virtual void fillVertexBuffersUpdated() {}
487 
488 private:
490  DrawParams previousFillDrawParams;
491 
492  bool containsDefault(const SphericalRegion* r) const;
493  bool intersectsDefault(const SphericalRegion* r) const;
494  SphericalRegionP getIntersectionDefault(const SphericalRegion* r) const;
495  SphericalRegionP getUnionDefault(const SphericalRegion* r) const;
496  SphericalRegionP getSubtractionDefault(const SphericalRegion* r) const;
497 };
498 
499 
505 {
506 public:
508  SphericalCap() : d(0) {;}
509 
511  SphericalCap(double x, double y, double z) : n(x,y,z), d(0) {;}
512 
516  SphericalCap(const Vec3d& an, double ar) : n(an), d(ar) {//n.normalize();
517  Q_ASSERT(d==0 || std::fabs(n.lengthSquared()-1.)<0.0000001);}
518  // TODO:FIXME! GZ reports 2013-03-02: apparently the Q_ASSERT is here because n should be normalized at this point, but
519  // for efficiency n.normalize() should not be called at this point.
520  // However, when zooming in a bit in Hammer-Aitoff and Mercator projections, this Assertion fires.
521  // Atmosphere must be active
522  // It may have to do with DSO texture rendering.
523  // found at r5863.
524  // n.normalize() prevents this for now, but may cost performance.
525  // AARGH - activating n.normalize() inhibits mouse-identification/selection of stars!
526  // May be compiler dependent (seen on Win/MinGW), AW cannot confirm it on Linux.
527 
529  SphericalCap(const SphericalCap& other) : SphericalRegion(), n(other.n), d(other.d) {;}
530 
531  virtual SphericalRegionType getType() const {return SphericalRegion::Cap;}
532  virtual OctahedronPolygon getOctahedronPolygon() const;
533 
535  virtual double getArea() const {return 2.*M_PI*(1.-d);}
536 
538  virtual bool isEmpty() const {return d>=1.;}
539 
541  virtual Vec3d getPointInside() const {return n;}
542 
544  virtual SphericalCap getBoundingCap() const {return *this;}
545 
546  // Contain and intersect
547  bool contains(const Vec3d &v) const
548  {
549  Q_ASSERT(d==0 || std::fabs(v.lengthSquared()-1.)<0.00000021);
550  return (v*n>=d);
551  }
552  virtual bool contains(const SphericalConvexPolygon& r) const;
553  virtual bool contains(const SphericalCap& h) const
554  {
555  const double a = n*h.n-d*h.d;
556  return d<=h.d && ( a>=1. || (a>=0. && a*a >= (1.-d*d)*(1.-h.d*h.d)));
557  }
558  virtual bool contains(const AllSkySphericalRegion&) const {return d<=-1;}
559  virtual bool intersects(const SphericalPolygon& r) const;
560  virtual bool intersects(const SphericalConvexPolygon& r) const;
564  virtual bool intersects(const SphericalCap& h) const
565  {
566  const double a = d*h.d - n*h.n;
567  return d+h.d<=0. || a<=0. || (a<=1. && a*a <= (1.-d*d)*(1.-h.d*h.d));
568  }
569  virtual bool intersects(const AllSkySphericalRegion&) const {return d<=1.;}
570 
574  virtual QVariantList toQVariant() const;
575 
576  virtual void serialize(QDataStream& out) const {out << n << d;}
577 
579  // Methods specific to SphericalCap
580 
582  double getRadius() const {return std::acos(d);}
583 
588  inline bool intersectsHalfSpace(double hn0, double hn1, double hn2) const
589  {
590  const double a = n[0]*hn0+n[1]*hn1+n[2]*hn2;
591  return d<=0. || a<=0. || (a<=1. && a*a <= (1.-d*d));
592  }
593 
596  bool clipGreatCircle(Vec3d& v1, Vec3d& v2) const;
597 
599  bool operator==(const SphericalCap& other) const {return (n==other.n && d==other.d);}
600 
602  QVector<Vec3d> getClosedOutlineContour() const;
603 
605  bool intersectsConvexContour(const Vec3d* vertice, int nbVertice) const;
606 
608  bool containsTriangle(const Triplet<Vec3d> triangle) const;
609 
611  bool intersectsTriangle(const Triplet<Vec3d>& triangle) const;
612 
614  static SphericalRegionP deserialize(QDataStream& in);
615 
618  static double relativeAreaOverlap(const SphericalCap& c1, const SphericalCap& c2);
619 
622  static double relativeDiameterOverlap(const SphericalCap& c1, const SphericalCap& c2);
623 
626  static bool intersectionPoints(const SphericalCap& h1, const SphericalCap& h2, Vec3d& p1, Vec3d& p2);
627 
631  double d;
632 };
633 
637 inline bool sideHalfSpaceContains(const Vec3d& v1, const Vec3d& v2, const Vec3d& p)
638 {
639  return (v1[1] * v2[2] - v1[2] * v2[1])*p[0] +
640  (v1[2] * v2[0] - v1[0] * v2[2])*p[1] +
641  (v1[0] * v2[1] - v1[1] * v2[0])*p[2]>=-1e-17;
642 }
643 
645 inline bool sideHalfSpaceContains(const Vec3d& v1, const Vec3d& v2, const SphericalCap& h)
646 {
647  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]);
648  n.normalize();
649  const double a = n*h.n;
650  return 0<=h.d && ( a>=1. || (a>=0. && a*a >= 1.-h.d*h.d));
651 }
652 
654 inline bool sideHalfSpaceIntersects(const Vec3d& v1, const Vec3d& v2, const SphericalCap& h)
655 {
656  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]);
657  n.normalize();
658  return h.intersectsHalfSpace(n[0], n[1], n[2]);
659 }
660 
664 {
665 public:
666  SphericalPoint(const Vec3d& an) : n(an) {Q_ASSERT(std::fabs(1.-n.length())<0.0000001);}
667  virtual ~SphericalPoint() {;}
668 
669  virtual SphericalRegionType getType() const {return SphericalRegion::Point;}
670  virtual OctahedronPolygon getOctahedronPolygon() const;
671  virtual double getArea() const {return 0.;}
672  virtual bool isEmpty() const {return false;}
673  virtual Vec3d getPointInside() const {return n;}
674  virtual SphericalCap getBoundingCap() const {return SphericalCap(n, 1);}
677  virtual QVariantList toQVariant() const;
678  virtual void serialize(QDataStream& out) const {out << n;}
679 
680  // Contain and intersect
681  virtual bool contains(const Vec3d& p) const {return n==p;}
682  virtual bool contains(const SphericalPolygon&) const {return false;}
683  virtual bool contains(const SphericalConvexPolygon&) const {return false;}
684  virtual bool contains(const SphericalCap&) const {return false;}
685  virtual bool contains(const SphericalPoint& r) const {return n==r.n;}
686  virtual bool contains(const AllSkySphericalRegion&) const {return false;}
687  virtual bool intersects(const SphericalPolygon&) const;
688  virtual bool intersects(const SphericalConvexPolygon&) const;
689  virtual bool intersects(const SphericalCap& r) const {return r.contains(n);}
690  virtual bool intersects(const SphericalPoint& r) const {return n==r.n;}
691  virtual bool intersects(const AllSkySphericalRegion&) const {return true;}
692 
694  static SphericalRegionP deserialize(QDataStream& in);
695 
698 };
699 
703 {
704 public:
705  virtual ~AllSkySphericalRegion() {;}
706 
707  virtual SphericalRegionType getType() const {return SphericalRegion::AllSky;}
709  {
710  return OctahedronPolygon::getAllSkyOctahedronPolygon();
711  }
712  virtual double getArea() const {return 4.*M_PI;}
713  virtual bool isEmpty() const {return false;}
714  virtual Vec3d getPointInside() const {return Vec3d(1,0,0);}
715  virtual SphericalCap getBoundingCap() const {return SphericalCap(Vec3d(1,0,0), -2);}
718  virtual QVariantList toQVariant() const;
719  virtual void serialize(QDataStream&) const {;}
720 
721  // Contain and intersect
722  virtual bool contains(const Vec3d&) const {return true;}
723  virtual bool contains(const SphericalPolygon&) const {return true;}
724  virtual bool contains(const SphericalConvexPolygon&) const {return true;}
725  virtual bool contains(const SphericalCap&) const {return true;}
726  virtual bool contains(const SphericalPoint&) const {return true;}
727  virtual bool contains(const AllSkySphericalRegion&) const {return true;}
728  virtual bool intersects(const SphericalPolygon&) const {return true;}
729  virtual bool intersects(const SphericalConvexPolygon&) const {return true;}
730  virtual bool intersects(const SphericalCap&) const {return true;}
731  virtual bool intersects(const SphericalPoint&) const {return true;}
732  virtual bool intersects(const AllSkySphericalRegion&) const {return true;}
733 
734  static const SphericalRegionP staticInstance;
735 };
736 
740 {
741 public:
742  // Avoid name hiding when overloading the virtual methods.
748 
750  virtual ~EmptySphericalRegion() {;}
751 
752  virtual SphericalRegionType getType() const {return SphericalRegion::Empty;}
754  {
755  return OctahedronPolygon::getEmptyOctahedronPolygon();
756  }
757  virtual double getArea() const {return 0.;}
758  virtual bool isEmpty() const {return true;}
759  virtual Vec3d getPointInside() const {return Vec3d(1,0,0);}
760  virtual SphericalCap getBoundingCap() const {return SphericalCap(Vec3d(1,0,0), 2);}
763  virtual QVariantList toQVariant() const;
764  virtual void serialize(QDataStream&) const {;}
765 
766  // Contain and intersect
767  virtual bool contains(const Vec3d&) const {return false;}
768  virtual bool contains(const SphericalPolygon&) const {return false;}
769  virtual bool contains(const SphericalConvexPolygon&) const {return false;}
770  virtual bool contains(const SphericalCap&) const {return false;}
771  virtual bool contains(const SphericalPoint&) const {return false;}
772  virtual bool contains(const AllSkySphericalRegion&) const {return false;}
773  virtual bool intersects(const SphericalPolygon&) const {return false;}
774  virtual bool intersects(const SphericalConvexPolygon&) const {return false;}
775  virtual bool intersects(const SphericalCap&) const {return false;}
776  virtual bool intersects(const SphericalPoint&) const {return false;}
777  virtual bool intersects(const AllSkySphericalRegion&) const {return false;}
778 
779  static const SphericalRegionP staticInstance;
780 };
781 
782 
787 {
788 public:
789  // Avoid name hiding when overloading the virtual methods.
795 
796  SphericalPolygon() {;}
798  SphericalPolygon(const QVector<QVector<Vec3d> >& contours) : octahedronPolygon(contours) {;}
800  SphericalPolygon(const QVector<Vec3d>& contour) : octahedronPolygon(contour) {;}
801  SphericalPolygon(const OctahedronPolygon& octContour) : octahedronPolygon(octContour) {;}
802  SphericalPolygon(const QList<OctahedronPolygon>& octContours) : octahedronPolygon(octContours) {;}
803 
804  virtual SphericalRegionType getType() const {return SphericalRegion::Polygon;}
806  {
807  return octahedronPolygon;
808  }
809 
814  virtual QVariantList toQVariant() const;
815  virtual void serialize(QDataStream& out) const;
816 
817  virtual SphericalCap getBoundingCap() const;
818 
819  virtual bool contains(const Vec3d& p) const {return octahedronPolygon.contains(p);}
820  virtual bool contains(const SphericalPolygon& r) const {return octahedronPolygon.contains(r.octahedronPolygon);}
821  virtual bool contains(const SphericalConvexPolygon& r) const;
822  virtual bool contains(const SphericalCap& r) const {return octahedronPolygon.contains(r.getOctahedronPolygon());}
823  virtual bool contains(const SphericalPoint& r) const {return octahedronPolygon.contains(r.n);}
824  virtual bool contains(const AllSkySphericalRegion& r) const {return octahedronPolygon.contains(r.getOctahedronPolygon());}
825 
826  virtual bool intersects(const SphericalPolygon& r) const {return octahedronPolygon.intersects(r.octahedronPolygon);}
827  virtual bool intersects(const SphericalConvexPolygon& r) const;
828  virtual bool intersects(const SphericalCap& r) const {return r.intersects(*this);}
829  virtual bool intersects(const SphericalPoint& r) const {return octahedronPolygon.contains(r.n);}
830  virtual bool intersects(const AllSkySphericalRegion&) const {return !isEmpty();}
831 
832  virtual SphericalRegionP getIntersection(const SphericalPoint& r) const {return contains(r.n) ? SphericalRegionP(new SphericalPoint(r)) : EmptySphericalRegion::staticInstance;}
833  virtual SphericalRegionP getIntersection(const AllSkySphericalRegion& ) const {return SphericalRegionP(new SphericalPolygon(octahedronPolygon));}
834 
835  virtual SphericalRegionP getUnion(const SphericalPoint&) const {return SphericalRegionP(new SphericalPolygon(octahedronPolygon));}
836  virtual SphericalRegionP getUnion(const EmptySphericalRegion&) const {return SphericalRegionP(new SphericalPolygon(octahedronPolygon));}
837 
838  virtual SphericalRegionP getSubtraction(const SphericalPoint&) const {return SphericalRegionP(new SphericalPolygon(octahedronPolygon));}
839  virtual SphericalRegionP getSubtraction(const EmptySphericalRegion&) const {return SphericalRegionP(new SphericalPolygon(octahedronPolygon));}
840 
842  // Methods specific to SphericalPolygon
846  void setContours(const QVector<QVector<Vec3d> >& contours)
847  {
848  octahedronPolygon = OctahedronPolygon(contours);
849  }
850 
853  void setContour(const QVector<Vec3d>& contour)
854  {
855  octahedronPolygon = OctahedronPolygon(contour);
856  }
857 
859  QVector<QVector<Vec3d> > getClosedOutlineContours() const {Q_ASSERT(0); return QVector<QVector<Vec3d> >();}
860 
862  static SphericalRegionP deserialize(QDataStream& in);
863 
865  static SphericalRegionP multiUnion(const QList<SphericalRegionP>& regions, bool optimizeByPreGrouping=false);
866 
868  static SphericalRegionP multiIntersection(const QList<SphericalRegionP>& regions);
869 
870 private:
871  OctahedronPolygon octahedronPolygon;
872 };
873 
874 
878 {
879 public:
880  // Avoid name hiding when overloading the virtual methods.
883 
886 
888  SphericalConvexPolygon(const QVector<QVector<Vec3d> >& contours)
890  {
891  Q_ASSERT(contours.size()==1);
892  setContour(contours.at(0));
893  }
894 
896  SphericalConvexPolygon(const QVector<Vec3d>& contour)
898  {
899  setContour(contour);
900  }
901 
903  SphericalConvexPolygon(const Vec3d &e0,const Vec3d &e1,const Vec3d &e2)
905  {
906  contour << e0 << e1 << e2; updateBoundingCap();
907  }
908 
910  SphericalConvexPolygon(const Vec3d &e0,const Vec3d &e1,const Vec3d &e2, const Vec3d &e3)
912  {
913  contour << e0 << e1 << e2 << e3; updateBoundingCap();
914  }
915 
916  virtual SphericalRegionType getType() const {return SphericalRegion::ConvexPolygon;}
917 
919  {
920  return OctahedronPolygon(contour);
921  }
922 
923  virtual const QVector<Vec3d>& getFillVertexPositions() const
924  {
925  return contour;
926  }
927 
928  virtual PrimitiveType getFillPrimitiveType() const
929  {
930  return PrimitiveType_TriangleFan;
931  }
932 
933  virtual const QVector<Vec3d>& getOutlineVertexPositions() const
934  {
935  return contour;
936  }
937 
938  virtual PrimitiveType getOutlinePrimitiveType() const
939  {
940  return PrimitiveType_LineLoop;
941  }
942 
943  virtual double getArea() const;
944  virtual bool isEmpty() const {return contour.isEmpty();}
945  virtual Vec3d getPointInside() const;
947  QVector<SphericalCap> getBoundingSphericalCaps() const;
952  virtual QVariantList toQVariant() const;
953  virtual void serialize(QDataStream& out) const {out << contour;}
954 
955  // Contain and intersect
956  virtual bool contains(const Vec3d& p) const;
957  virtual bool contains(const SphericalPolygon& r) const;
958  virtual bool contains(const SphericalConvexPolygon& r) const;
959  virtual bool contains(const SphericalCap& r) const;
960  virtual bool contains(const SphericalPoint& r) const {return contains(r.n);}
961  virtual bool contains(const AllSkySphericalRegion&) const {return false;}
962  virtual bool intersects(const SphericalCap& r) const {if (!cachedBoundingCap.intersects(r)) return false; return r.intersects(*this);}
963  virtual bool intersects(const SphericalPolygon& r) const;
964  virtual bool intersects(const SphericalConvexPolygon& r) const;
965  virtual bool intersects(const SphericalPoint& r) const {return contains(r.n);}
966  virtual bool intersects(const AllSkySphericalRegion&) const {return true;}
967 
969 // virtual SphericalRegionP getIntersection(const SphericalPolygon& r) const;
970 // virtual SphericalRegionP getIntersection(const SphericalConvexPolygon& r) const;
971 // virtual SphericalRegionP getIntersection(const SphericalCap& r) const;
972 // virtual SphericalRegionP getIntersection(const SphericalPoint& r) const;
973 // virtual SphericalRegionP getIntersection(const AllSkySphericalRegion& r) const;
974 // virtual SphericalRegionP getUnion(const SphericalPolygon& r) const;
975 // virtual SphericalRegionP getUnion(const SphericalConvexPolygon& r) const;
976 // virtual SphericalRegionP getUnion(const SphericalCap& r) const;
977 // virtual SphericalRegionP getUnion(const SphericalPoint& r) const;
978 // virtual SphericalRegionP getUnion(const EmptySphericalRegion& r) const;
979 // virtual SphericalRegionP getSubtraction(const SphericalPolygon& r) const;
980 // virtual SphericalRegionP getSubtraction(const SphericalConvexPolygon& r) const;
981 // virtual SphericalRegionP getSubtraction(const SphericalCap& r) const;
982 // virtual SphericalRegionP getSubtraction(const SphericalPoint& r) const;
983 // virtual SphericalRegionP getSubtraction(const EmptySphericalRegion& r) const;
984 
986  // Methods specific to SphericalConvexPolygon
990  void setContour(const QVector<Vec3d>& acontour)
991  {
992  contour = acontour;
995  }
996 
998  const QVector<Vec3d>& getConvexContour() const {return contour;}
999 
1001  bool checkValid() const;
1002 
1004  static bool checkValidContour(const QVector<Vec3d>& contour);
1005 
1007  static SphericalRegionP deserialize(QDataStream& in);
1008 
1009 protected:
1011  QVector<Vec3d> contour;
1012 
1015 
1018 
1020  void updateBoundingCap();
1021 
1022  virtual void updateFillVertexBuffer(class StelRenderer* renderer, const DrawParams& params, bool handleDiscontinuity);
1023 
1024  virtual void drawFillVertexBuffer(class StelRenderer* renderer, class StelProjector* projector);
1025 
1026  virtual bool needToUpdateFillVertexBuffers() const
1027  {
1029  }
1030 
1032  {
1034  }
1035 
1041  static bool areAllPointsOutsideOneSide(const Vec3d* thisContour, int nbThisContour, const Vec3d* points, int nbPoints);
1042 
1044  bool areAllPointsOutsideOneSide(const QVector<Vec3d>& points) const
1045  {
1046  return areAllPointsOutsideOneSide(contour.constData(), contour.size(), points.constData(), points.size());
1047  }
1048 
1049  bool containsConvexContour(const Vec3d* vertice, int nbVertex) const;
1050 };
1051 
1052 
1055 //class SphericalConvexPolygonSet : public SphericalRegion
1056 //{
1057 //public:
1058 // // Avoid name hiding when overloading the virtual methods.
1059 // using SphericalRegion::intersects;
1060 // using SphericalRegion::contains;
1061 //
1062 // //! Default constructor.
1063 // SphericalConvexPolygonSet() {;}
1064 //
1065 // //! Constructor from a list of contours.
1066 // SphericalConvexPolygonSet(const QVector<QVector<Vec3d> >& contours);
1067 //
1068 // virtual SphericalRegionType getType() const {return SphericalRegion::ConvexPolygonSet;}
1069 // virtual OctahedronPolygon getOctahedronPolygon() const;
1070 // virtual StelVertexArray getFillVertexArray() const;
1071 // virtual StelVertexArray getOutlineVertexArray() const;
1072 // virtual double getArea() const;
1073 // virtual bool isEmpty() const;
1074 // virtual Vec3d getPointInside() const;
1075 // virtual SphericalCap getBoundingCap() const {return cachedBoundingCap;}
1076 // QVector<SphericalCap> getBoundingSphericalCaps() const;
1077 // //! Serialize the region into a QVariant map matching the JSON format.
1078 // //! The format is
1079 // //! @code["CONVEX_POLYGON_SET", [[ra,dec], [ra,dec], [ra,dec], [ra,dec]], [[ra,dec], [ra,dec], [ra,dec], [ra,dec]]]@endcode
1080 // //! where the coords from a list of closed convex contour, with each points defined by ra dec in degree in the ICRS frame.
1081 // virtual QVariantList toQVariant() const;
1082 // virtual void serialize(QDataStream& out) const;
1083 //
1084 // // Contain and intersect
1085 // virtual bool contains(const Vec3d& p) const;
1086 // virtual bool contains(const SphericalPolygon& r) const;
1087 // virtual bool contains(const SphericalConvexPolygon& r) const;
1088 // virtual bool contains(const SphericalCap& r) const;
1089 // virtual bool contains(const SphericalPoint& r) const {return contains(r.n);}
1090 // virtual bool contains(const AllSkySphericalRegion&) const {return false;}
1091 // virtual bool intersects(const SphericalCap& r) const {if (!cachedBoundingCap.intersects(r)) return false; return r.intersects(*this);}
1092 // virtual bool intersects(const SphericalPolygon& r) const;
1093 // virtual bool intersects(const SphericalConvexPolygon& r) const;
1094 // virtual bool intersects(const SphericalPoint& r) const {return contains(r.n);}
1095 // virtual bool intersects(const AllSkySphericalRegion&) const {return true;}
1096 //
1097 // ////////////////////////////////////////////////////////////////////
1098 // // Methods specific to SphericalConvexPolygonSet
1099 // ////////////////////////////////////////////////////////////////////
1100 // //! Deserialize the region. This method must allow as fast as possible deserialization.
1101 // static SphericalRegionP deserialize(QDataStream& in);
1102 //
1103 //protected:
1104 // QVector<SphericalConvexPolygon> contours;
1105 //
1106 // //! Cache the bounding cap.
1107 // SphericalCap cachedBoundingCap;
1108 //
1109 // //! Update the bounding cap from the vertex list.
1110 // void updateBoundingCap();
1111 //};
1112 
1113 
1117 {
1118 public:
1121  {
1123  }
1124 
1126  SphericalTexturedConvexPolygon(const QVector<Vec3d>& contour, const QVector<Vec2f>& texCoord)
1127  : fillTexturedVertexBuffer(NULL)
1128  {
1129  setContour(contour, texCoord);
1131  }
1132 
1135  SphericalTexturedConvexPolygon(const Vec3d &e0,const Vec3d &e1,const Vec3d &e2, const Vec3d &e3)
1136  : SphericalConvexPolygon(e0,e1,e2,e3)
1137  , fillTexturedVertexBuffer(NULL)
1138  {
1139  textureCoords << Vec2f(0.f, 0.f) << Vec2f(1.f, 0.f) << Vec2f(1.f, 1.f) << Vec2f(0.f, 1.f);
1141  }
1142 
1144  {
1145  if(NULL != fillTexturedVertexBuffer)
1146  {
1147  delete fillTexturedVertexBuffer;
1148  }
1149  }
1150 
1154  virtual void setContour(const QVector<Vec3d>& acontour, const QVector<Vec2f>& texCoord)
1155  {
1157  textureCoords=texCoord;
1159  }
1160 
1167  virtual QVariantList toQVariant() const;
1168 
1169  virtual void serialize(QDataStream& out) const {out << contour << textureCoords;}
1170 
1171 protected:
1174  QVector<Vec2f> textureCoords;
1175 
1178 
1179  virtual void updateFillVertexBuffer(class StelRenderer* renderer, const DrawParams& params, bool handleDiscontinuity);
1180 
1181  virtual void drawFillVertexBuffer(class StelRenderer* renderer, class StelProjector* projector);
1182 };
1183 
1184 
1192 Vec3d greatCircleIntersection(const Vec3d& p1, const Vec3d& p2, const Vec3d& p3, const Vec3d& p4, bool& ok);
1193 
1200 Vec3d greatCircleIntersection(const Vec3d& p1, const Vec3d& p2, const Vec3d& nHalfSpace, bool& ok);
1201 
1202 #endif // _STELSPHEREGEOMETRY_HPP_
1203