Stellarium 0.13.1
OctahedronPolygon.hpp
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 _OCTAHEDRON_REGION_HPP_
21 #define _OCTAHEDRON_REGION_HPP_
22 
23 #include "config.h"
24 
25 #include "StelVertexArray.hpp"
26 #include "VecMath.hpp"
27 
28 #include <QVector>
29 #include <QDebug>
30 #include <QVarLengthArray>
31 
34 struct EdgeVertex
35 {
36  EdgeVertex() : edgeFlag(false) {;}
37  EdgeVertex(bool b) : edgeFlag(b) {;}
38  EdgeVertex(const Vec3d& v, bool b) : vertex(v), edgeFlag(b) {;}
42  bool edgeFlag;
43 };
44 
45 Q_DECLARE_TYPEINFO(EdgeVertex, Q_PRIMITIVE_TYPE);
46 
47 QDataStream& operator<<(QDataStream& out, const EdgeVertex&);
48 QDataStream& operator>>(QDataStream& in, EdgeVertex&);
49 
50 class SubContour : public QVector<EdgeVertex>
51 {
52 public:
53  // Create a SubContour from a list of vertices
54  SubContour(const QVector<Vec3d>& vertices, bool closed=true);
55  SubContour() {;}
56  SubContour(int size, const EdgeVertex& v) : QVector<EdgeVertex>(size, v) {;}
57  SubContour reversed() const;
58  QString toJSON() const;
59 };
60 
66 {
67 public:
68  OctahedronPolygon() : fillCachedVertexArray(StelVertexArray::Triangles), outlineCachedVertexArray(StelVertexArray::Lines), capN(1,0,0), capD(-2.)
69  {sides.resize(8);}
70 
72  OctahedronPolygon(const SubContour& subContour);
73  OctahedronPolygon(const QVector<QVector<Vec3d> >& contours);
74  OctahedronPolygon(const QVector<Vec3d>& contour);
75  OctahedronPolygon(const QList<OctahedronPolygon>& octContours);
76 
77  double getArea() const;
78 
79  Vec3d getPointInside() const;
80 
82  StelVertexArray getFillVertexArray() const {return fillCachedVertexArray;}
83  StelVertexArray getOutlineVertexArray() const {return outlineCachedVertexArray;}
84 
85  void getBoundingCap(Vec3d& v, double& d) const {v=capN; d=capD;}
86 
88  void inPlaceIntersection(const OctahedronPolygon& mpoly);
90  void inPlaceUnion(const OctahedronPolygon& mpoly);
92  void inPlaceSubtraction(const OctahedronPolygon& mpoly);
93 
94  bool intersects(const OctahedronPolygon& mpoly) const;
95  bool contains(const OctahedronPolygon& mpoly) const;
96 
97  bool contains(const Vec3d& p) const;
98  bool isEmpty() const;
99 
100  static const OctahedronPolygon& getAllSkyOctahedronPolygon();
101  static const OctahedronPolygon& getEmptyOctahedronPolygon() {static OctahedronPolygon poly; return poly;}
102 
103  static double sphericalTriangleArea(const Vec3d& v0, const Vec3d& v1, const Vec3d& v2)
104  {
105  const Vec3d& p1 = v0 ^ v1;
106  const Vec3d& p2 = v1 ^ v2;
107  const Vec3d& p3 = v2 ^ v0;
108  return 2.*M_PI - p1.angle(p2) - p2.angle(p3) - p3.angle(p1);
109  }
110 
111  QString toJson() const;
112 
113 private:
114  // For unit tests
115  friend class TestStelSphericalGeometry;
116 
117  friend QDataStream& operator<<(QDataStream&, const OctahedronPolygon&);
118  friend QDataStream& operator>>(QDataStream&, OctahedronPolygon&);
119  friend OctahedronPolygon createAllSkyOctahedronPolygon();
120 
122  static OctahedronPolygon createAllSkyOctahedronPolygon();
123 
126  void append(const OctahedronPolygon& other);
127  void appendReversed(const OctahedronPolygon& other);
128  void appendSubContour(const SubContour& contour);
129 
130  enum TessWindingRule
131  {
132  WindingPositive=0,
133  WindingAbsGeqTwo=1
134  };
135 
136  bool sideContains2D(const Vec3d& p, int sideNb) const;
137 
139  void tesselate(TessWindingRule rule);
140 
141  QVector<SubContour> tesselateOneSideLineLoop(struct GLUEStesselator* tess, int sidenb) const;
142  QVector<Vec3d> tesselateOneSideTriangles(struct GLUEStesselator* tess, int sidenb) const;
143  QVarLengthArray<QVector<SubContour>,8 > sides;
144 
146  void updateVertexArray();
147  StelVertexArray fillCachedVertexArray;
148  StelVertexArray outlineCachedVertexArray;
149  void computeBoundingCap();
150  Vec3d capN;
151  double capD;
152 
153  static const Vec3d sideDirections[];
154  static int getSideNumber(const Vec3d& v) {return v[0]>=0. ? (v[1]>=0. ? (v[2]>=0.?0:1) : (v[2]>=0.?4:5)) : (v[1]>=0. ? (v[2]>=0.?2:3) : (v[2]>=0.?6:7));}
155  static bool isTriangleConvexPositive2D(const Vec3d& a, const Vec3d& b, const Vec3d& c);
156  static bool triangleContains2D(const Vec3d& a, const Vec3d& b, const Vec3d& c, const Vec3d& p);
157 
158  static void projectOnOctahedron(QVarLengthArray<QVector<SubContour>,8 >& inSides);
159  static void splitContourByPlan(int onLine, const SubContour& contour, QVector<SubContour> result[2]);
160 };
161 
162 // Serialization routines
163 QDataStream& operator<<(QDataStream& out, const OctahedronPolygon&);
164 QDataStream& operator>>(QDataStream& in, OctahedronPolygon&);
165 
166 #endif // _OCTAHEDRON_REGION_HPP_
167 
Describe a vertex composing polygon contours, and whether it belong to an edge or not...
Vec3d vertex
The normalized vertex direction.
Manage a non-convex polygon which can extends on more than 180 deg.
StelVertexArray getFillVertexArray() const
Returns the list of triangles resulting from tesselating the contours.
bool edgeFlag
Set to true if the vertex is part of at least one edge segment, i.e. it lays on the boundary of the p...
QDataStream & operator<<(QDataStream &out, const SphericalRegionP &region)
Serialize the passed SphericalRegionP into a binary blob.
void inPlaceIntersection(const OctahedronPolygon &mpoly)
Set this OctahedronPolygon as the intersection of itself with the given OctahedronPolygon.
void inPlaceUnion(const OctahedronPolygon &mpoly)
Set this OctahedronPolygon as the union of itself with the given OctahedronPolygon.
QDataStream & operator>>(QDataStream &in, SphericalRegionP &region)
Load the SphericalRegionP from a binary blob.
void inPlaceSubtraction(const OctahedronPolygon &mpoly)
Set this OctahedronPolygon as the subtraction of itself with the given OctahedronPolygon.