Stellarium 0.13.2
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 "StelVertexArray.hpp"
24 #include "VecMath.hpp"
25 
26 #include <QVector>
27 #include <QDebug>
28 #include <QVarLengthArray>
29 
32 struct EdgeVertex
33 {
34  EdgeVertex() : edgeFlag(false) {;}
35  EdgeVertex(bool b) : edgeFlag(b) {;}
36  EdgeVertex(const Vec3d& v, bool b) : vertex(v), edgeFlag(b) {;}
40  bool edgeFlag;
41 };
42 
43 Q_DECLARE_TYPEINFO(EdgeVertex, Q_PRIMITIVE_TYPE);
44 
45 QDataStream& operator<<(QDataStream& out, const EdgeVertex&);
46 QDataStream& operator>>(QDataStream& in, EdgeVertex&);
47 
48 class SubContour : public QVector<EdgeVertex>
49 {
50 public:
51  // Create a SubContour from a list of vertices
52  SubContour(const QVector<Vec3d>& vertices, bool closed=true);
53  SubContour() {;}
54  SubContour(int size, const EdgeVertex& v) : QVector<EdgeVertex>(size, v) {;}
55  SubContour reversed() const;
56  QString toJSON() const;
57 };
58 
64 {
65 public:
66  OctahedronPolygon() : fillCachedVertexArray(StelVertexArray::Triangles), outlineCachedVertexArray(StelVertexArray::Lines), capN(1,0,0), capD(-2.)
67  {sides.resize(8);}
68 
70  OctahedronPolygon(const SubContour& subContour);
71  OctahedronPolygon(const QVector<QVector<Vec3d> >& contours);
72  OctahedronPolygon(const QVector<Vec3d>& contour);
73  OctahedronPolygon(const QList<OctahedronPolygon>& octContours);
74 
75  double getArea() const;
76 
77  Vec3d getPointInside() const;
78 
80  StelVertexArray getFillVertexArray() const {return fillCachedVertexArray;}
81  StelVertexArray getOutlineVertexArray() const {return outlineCachedVertexArray;}
82 
83  void getBoundingCap(Vec3d& v, double& d) const {v=capN; d=capD;}
84 
86  void inPlaceIntersection(const OctahedronPolygon& mpoly);
88  void inPlaceUnion(const OctahedronPolygon& mpoly);
90  void inPlaceSubtraction(const OctahedronPolygon& mpoly);
91 
92  bool intersects(const OctahedronPolygon& mpoly) const;
93  bool contains(const OctahedronPolygon& mpoly) const;
94 
95  bool contains(const Vec3d& p) const;
96  bool isEmpty() const;
97 
98  static const OctahedronPolygon& getAllSkyOctahedronPolygon();
99  static const OctahedronPolygon& getEmptyOctahedronPolygon() {static OctahedronPolygon poly; return poly;}
100 
101  static double sphericalTriangleArea(const Vec3d& v0, const Vec3d& v1, const Vec3d& v2)
102  {
103  const Vec3d& p1 = v0 ^ v1;
104  const Vec3d& p2 = v1 ^ v2;
105  const Vec3d& p3 = v2 ^ v0;
106  return 2.*M_PI - p1.angle(p2) - p2.angle(p3) - p3.angle(p1);
107  }
108 
109  QString toJson() const;
110 
111 private:
112  // For unit tests
113  friend class TestStelSphericalGeometry;
114 
115  friend QDataStream& operator<<(QDataStream&, const OctahedronPolygon&);
116  friend QDataStream& operator>>(QDataStream&, OctahedronPolygon&);
117  friend OctahedronPolygon createAllSkyOctahedronPolygon();
118 
120  static OctahedronPolygon createAllSkyOctahedronPolygon();
121 
124  void append(const OctahedronPolygon& other);
125  void appendReversed(const OctahedronPolygon& other);
126  void appendSubContour(const SubContour& contour);
127 
128  enum TessWindingRule
129  {
130  WindingPositive=0,
131  WindingAbsGeqTwo=1
132  };
133 
134  bool sideContains2D(const Vec3d& p, int sideNb) const;
135 
137  void tesselate(TessWindingRule rule);
138 
139  QVector<SubContour> tesselateOneSideLineLoop(struct GLUEStesselator* tess, int sidenb) const;
140  QVector<Vec3d> tesselateOneSideTriangles(struct GLUEStesselator* tess, int sidenb) const;
141  QVarLengthArray<QVector<SubContour>,8 > sides;
142 
144  void updateVertexArray();
145  StelVertexArray fillCachedVertexArray;
146  StelVertexArray outlineCachedVertexArray;
147  void computeBoundingCap();
148  Vec3d capN;
149  double capD;
150 
151  static const Vec3d sideDirections[];
152  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));}
153  static bool isTriangleConvexPositive2D(const Vec3d& a, const Vec3d& b, const Vec3d& c);
154  static bool triangleContains2D(const Vec3d& a, const Vec3d& b, const Vec3d& c, const Vec3d& p);
155 
156  static void projectOnOctahedron(QVarLengthArray<QVector<SubContour>,8 >& inSides);
157  static void splitContourByPlan(int onLine, const SubContour& contour, QVector<SubContour> result[2]);
158 };
159 
160 // Serialization routines
161 QDataStream& operator<<(QDataStream& out, const OctahedronPolygon&);
162 QDataStream& operator>>(QDataStream& in, OctahedronPolygon&);
163 
164 #endif // _OCTAHEDRON_REGION_HPP_
165 
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.