Stellarium 0.12.3
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 <QVector>
24 #include <QDebug>
25 #include <QVarLengthArray>
26 #include "VecMath.hpp"
27 
28 
31 struct EdgeVertex
32 {
33  EdgeVertex() : edgeFlag(false) {;}
34  EdgeVertex(bool b) : edgeFlag(b) {;}
35  EdgeVertex(const Vec3d& v, bool b) : vertex(v), edgeFlag(b) {;}
39  bool edgeFlag;
40 };
41 
42 Q_DECLARE_TYPEINFO(EdgeVertex, Q_PRIMITIVE_TYPE);
43 
44 QDataStream& operator<<(QDataStream& out, const EdgeVertex&);
45 QDataStream& operator>>(QDataStream& in, EdgeVertex&);
46 
47 class SubContour : public QVector<EdgeVertex>
48 {
49 public:
50  // Create a SubContour from a list of vertices
51  SubContour(const QVector<Vec3d>& vertices, bool closed=true);
52  SubContour() {;}
53  SubContour(int size, const EdgeVertex& v) : QVector<EdgeVertex>(size, v) {;}
54  SubContour reversed() const;
55  QString toJSON() const;
56 };
57 
63 {
64 public:
66  : capN(1,0,0)
67  , capD(-2.)
68  {
69  sides.resize(8);
70  }
71 
73  OctahedronPolygon(const SubContour& subContour);
74  OctahedronPolygon(const QVector<QVector<Vec3d> >& contours);
75  OctahedronPolygon(const QVector<Vec3d>& contour);
76  OctahedronPolygon(const QList<OctahedronPolygon>& octContours);
77 
78  double getArea() const;
79 
80  Vec3d getPointInside() const;
81 
82  void getBoundingCap(Vec3d& v, double& d) const {v=capN; d=capD;}
83 
85  void inPlaceIntersection(const OctahedronPolygon& mpoly);
87  void inPlaceUnion(const OctahedronPolygon& mpoly);
89  void inPlaceSubtraction(const OctahedronPolygon& mpoly);
90 
91  bool intersects(const OctahedronPolygon& mpoly) const;
92  bool contains(const OctahedronPolygon& mpoly) const;
93 
94  bool contains(const Vec3d& p) const;
95  bool isEmpty() const;
96 
97  static const OctahedronPolygon& getAllSkyOctahedronPolygon();
98  static const OctahedronPolygon& getEmptyOctahedronPolygon()
99  {
100  static OctahedronPolygon poly; return poly;
101  }
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 
114  const QVector<Vec3d>& fillVertices() const
115  {
116  return fillCachedVertexArray;
117  }
118 
120  const QVector<Vec3d>& outlineVertices() const
121  {
122  return outlineCachedVertexArray;
123  }
124 
125 private:
126  // For unit tests
127  friend class TestStelSphericalGeometry;
128 
129  friend QDataStream& operator<<(QDataStream&, const OctahedronPolygon&);
130  friend QDataStream& operator>>(QDataStream&, OctahedronPolygon&);
131  friend OctahedronPolygon createAllSkyOctahedronPolygon();
132 
134  static OctahedronPolygon createAllSkyOctahedronPolygon();
135 
138  void append(const OctahedronPolygon& other);
139  void appendReversed(const OctahedronPolygon& other);
140  void appendSubContour(const SubContour& contour);
141 
142  enum TessWindingRule
143  {
144  WindingPositive=0,
145  WindingAbsGeqTwo=1
146  };
147 
148  bool sideContains2D(const Vec3d& p, int sideNb) const;
149 
151  void tesselate(TessWindingRule rule);
152 
153  QVector<SubContour> tesselateOneSideLineLoop(struct GLUEStesselator* tess, int sidenb) const;
154  QVector<Vec3d> tesselateOneSideTriangles(struct GLUEStesselator* tess, int sidenb) const;
155  QVarLengthArray<QVector<SubContour>,8 > sides;
156 
158  void updateVertexArray();
159 
161  QVector<Vec3d> fillCachedVertexArray;
163  QVector<Vec3d> outlineCachedVertexArray;
164 
165  void computeBoundingCap();
166  Vec3d capN;
167  double capD;
168 
169  static const Vec3d sideDirections[];
170  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));}
171  static bool isTriangleConvexPositive2D(const Vec3d& a, const Vec3d& b, const Vec3d& c);
172  static bool triangleContains2D(const Vec3d& a, const Vec3d& b, const Vec3d& c, const Vec3d& p);
173 
174  static void projectOnOctahedron(QVarLengthArray<QVector<SubContour>,8 >& inSides);
175  static void splitContourByPlan(int onLine, const SubContour& contour, QVector<SubContour> result[2]);
176 };
177 
178 // Serialization routines
179 QDataStream& operator<<(QDataStream& out, const OctahedronPolygon&);
180 QDataStream& operator>>(QDataStream& in, OctahedronPolygon&);
181 
182 #endif // _OCTAHEDRON_REGION_HPP_
183