StelSphereGeometry.hpp   StelSphereGeometry.hpp 
/* /*
* Stellarium * Stellarium
* Copyright (C) 2007 Guillaume Chereau * Copyright (C) 2009 Fabien Chereau
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2 * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. * of the License, or (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, U SA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, U SA.
*/ */
#ifndef _STELSPHEREGEOMETRY_HPP_ #ifndef _STELSPHEREGEOMETRY_HPP_
#define _STELSPHEREGEOMETRY_HPP_ #define _STELSPHEREGEOMETRY_HPP_
#include <vector> #include <QVector>
#include <QVariant>
#include <QDebug>
#include <QSharedPointer>
#include <QVarLengthArray>
#include "VecMath.hpp" #include "VecMath.hpp"
#include "OctahedronPolygon.hpp"
#include "StelVertexArray.hpp"
//! @namespace StelGeom In this namespace we define different geometrical s class SphericalRegion;
hapes. class SphericalPolygon;
//! We also define two functions, contains(x, y) and intersect(x, y) = inte class SphericalConvexPolygon;
rsect(y, x) class SphericalCap;
//! which is defined for most of the pair of geometrical shapes. class SphericalPoint;
namespace StelGeom class AllSkySphericalRegion;
{ class EmptySphericalRegion;
/****************
Now the geometrical objects //! @file StelSphereGeometry.hpp
*****************/ //! Define all SphericalGeometry primitives as well as the SphericalRegionP
type.
template<class T>
bool intersect(const Vec3d& v, const T& o) //! @class SphericalRegionP
{ return contains(o, v); } //! A shared pointer on a SphericalRegion.
class SphericalRegionP : public QSharedPointer<SphericalRegion>
template<class T>
bool intersect(const T& o, const Vec3d& v)
{ return contains(o, v); }
//! @class HalfSpace
//! A HalfSpace is defined by a direction and an aperture.
//! It forms a cone from the center of the Coordinate frame with a radius d
struct HalfSpace
{
HalfSpace() : d(0) {}
HalfSpace(const Vec3d& an) : n(an), d(0) {}
//! Construct a HalfSpace from its direction and aperture
//! @param an a unit vector indicating the direction
//! @param ar cosinus of the aperture
HalfSpace(const Vec3d& an, double ar) : n(an), d(ar) {;}
HalfSpace(const HalfSpace& other) : n(other.n), d(other.d) {}
bool contains(const Vec3d &v) const {return (v*n>=d);}
bool operator==(const HalfSpace& other) const {return (n==other.n &&
d==other.d);}
//! Get the area of the halfspace in steradian
double getArea() const {return 2.*M_PI*(1.-d);}
//! The direction unit vector
Vec3d n;
//! The cos of cone radius
double d;
};
//! @class Polygon
//! A polygon is defined by a set of connected points.
//! The last point is connected to the first one
class Polygon : public std::vector<Vec3d>
{ {
public: public:
//! Default contructor // Override the constructors of QSharedPointer
Polygon(int asize = 0) : std::vector<Vec3d>(asize) {} SphericalRegionP() {;}
//! Special constructor for 3 points polygon SphericalRegionP(SphericalRegion* ptr) : QSharedPointer<SphericalReg
Polygon(const Vec3d &e0,const Vec3d &e1,const Vec3d &e2); ion>(ptr) {;}
//! Special constructor for 4 points polygon template <class Deleter> SphericalRegionP(SphericalRegion* ptr, Dele
Polygon(const Vec3d &e0,const Vec3d &e1,const Vec3d &e2, const Vec3d &e ter deleter) : QSharedPointer<SphericalRegion>(ptr, deleter) {;}
3); SphericalRegionP(const SphericalRegionP& other) : QSharedPointer<Sph
ericalRegion>(other) {;}
SphericalRegionP(const QWeakPointer<SphericalRegion>& other) : QShar
edPointer<SphericalRegion>(other) {;}
//! Create a SphericalRegion from the given input JSON stream.
//! The type of the region is automatically recognized from the inpu
t format.
//! The currently recognized format are:
//! <ul>
//! <li>Contour list:
//! @code[[contour1], [contour2],[...]]@endcode
//! This format consists of a list of contours. Contours defined in
counterclockwise direction (CW) are
//! added to the final region while CCW contours are subtracted (the
y can be used to form complex polygons even with holes).
//! Each contour can have different format:
//! <ul>
//! <li>
//! @code[[ra,dec], [ra,dec], [ra,dec], [ra,dec]]@endcode
//! A list of points connected by great circles with the last point
connected to the first one.
//! Each point is defined by its ra,dec coordinates in degrees.</li>
//! <li>
//! @code["CAP", [raCenter,decCenter], ap]@endcode
//! A spherical cap centered on raCenter/decCenter with aperture rad
ius ap in degrees. For example:
//! @code["CAP", [0.,-90.], 90]@endcode
//! define the region covering the entire southern hemisphere.</li>
//! <li>
//! @code["PATH", [startRa,startDec], [[prim1],[prim2],[prim3],...]]
@endcode
//! A path is a contour starting a startRa/startDec and defined by a
list of primitives. Each primitive can be either
//! a great circle or a small circle. Great circles are defined by t
he point to link to: ["greatCircleTo", [ra,dec]]. Small
//! circles are defined by a rotation axis and a rotation angle: ["s
mallCircle",[0,90],-88]. A full example is:
//! @code["PATH",[330,-25],[["smallCircle",[0,90],82.5],["greatCircl
eTo",[52.5,-35]],["smallCircle",[0,90],-82.5]]]@endcode
//! This defines a box of 82.5x10 degrees following latitude and lon
gitude lines.</li>
//! </ul>
//! <li>Polygon vertex list with associated texture coordinates:
//! @code{
//! "worldCoords": [[[ra,dec],[ra,dec],[ra,dec],[ra,dec]], [[ra,
dec],[ra,dec],[ra,dec]],[...]],
//! "textureCoords": [[[u,v],[u,v],[u,v],[u,v]], [[u,v],[u,v],[u
,v]], [...]]
//! }@endcode
//! The format is used to describe textured polygons. The worldCoord
s part is similar to the one described above.
//! The textureCoords part is the addition of a list of texture coor
dinates in the u,v texture space (between 0 and 1).
//! There must be one texture coordinate for each vertex.</li>
//! </ul>
//! @param in an open QIODevice ready for read.
//! @throws std::runtime_error when there was an error while parsing
the file.
static SphericalRegionP loadFromJson(QIODevice* in);
//! Create a SphericalRegion from the given QByteArray containing th
e JSON data.
//! @see loadFromJson(QIODevice* in) for format info.
static SphericalRegionP loadFromJson(const QByteArray& a);
//! Create a SphericalRegion from the given QVariantMap with a forma
t matching the JSON file parsed in loadFromJson().
//! @param map a valid QVariantMap which can be created e.g. from pa
rsing a JSON file with the StelJsonParser class.
static SphericalRegionP loadFromQVariant(const QVariantMap& map);
static SphericalRegionP loadFromQVariant(const QVariantList& list);
//! The QVariant type associated to a SphericalRegionP.
static const QVariant::Type qVariantType;
//! The meta type ID associated to a SphericalRegionP.
static int metaTypeId;
private:
static QVector<QVector<Vec3d> > loadContourFromQVariant(const QVaria
ntList& contoursList);
//! Initialize stuff to allow SphericalRegionP to be used with Qt me
ta type system.
static int initialize();
}; };
template<class T> // Allow to use SphericalRegionP with the Qt MetaType system.
bool intersect(const Polygon& p, const T& o) Q_DECLARE_METATYPE(SphericalRegionP);
{
return intersect(o, p);
}
//! @class ConvexS //! Serialize the passed SphericalRegionP into a binary blob.
//! A Convex is defined by several HalfSpaces defining a convex region. QDataStream& operator<<(QDataStream& out, const SphericalRegionP& region);
//! A Convex region is not necessarily a ConvexPolygon, it can for example //! Load the SphericalRegionP from a binary blob.
be a single HalfSpace. QDataStream& operator>>(QDataStream& in, SphericalRegionP& region);
//! Because in X11, Convex is \#defined as an int in X11/X.h: (\#define Con
vex 2) we needed to use another name (ConvexS). //! @class SphericalRegion
class ConvexS : public std::vector<HalfSpace> //! Abstract class defining a region of the sphere. It provides default imp
lementation for the general non-convex polygon
//! which can extend on more than 180 deg based on the OctahedronPolygon cl
ass.
//! Subclasses provides special faster implementations of many methods.
class SphericalRegion
{ {
public: public:
//! copy constructor //! @enum SphericalRegionType define types for all supported regions
ConvexS(const ConvexS& c) : std::vector<HalfSpace>(c) {} .
//! Default constructor enum SphericalRegionType
ConvexS(int asize = 0) : std::vector<HalfSpace>(asize) {}
//! Special constructor for 3 halfspaces convex
ConvexS(const Vec3d &e0,const Vec3d &e1,const Vec3d &e2);
//! Special constructor for 4 halfspaces convex
ConvexS(const Vec3d &e0,const Vec3d &e1,const Vec3d &e2, const Vec3d &e
3);
//! Tell whether the points of the passed Polygon are all outside of
at least one HalfSpace
bool areAllPointsOutsideOneSide(const Polygon& poly) const
{ {
for (const_iterator iter=begin();iter!=end();++iter) Point = 0,
{ Cap = 1,
bool allOutside = true; AllSky = 2,
for (Polygon::const_iterator v=poly.begin();v!=poly. Polygon = 3,
end()&& allOutside==true;++v) ConvexPolygon = 4,
{ Empty = 5
allOutside = allOutside && !iter->contains(* };
v);
} virtual ~SphericalRegion() {;}
if (allOutside)
return true; virtual SphericalRegionType getType() const = 0;
}
return false; //! Return the octahedron contour representation of the polygon.
} //! It can be used for safe computation of intersection/union in the
general case.
virtual OctahedronPolygon getOctahedronPolygon() const =0;
//! Return the area of the region in steradians.
virtual double getArea() const {return getOctahedronPolygon().getAre
a();}
//! Return true if the region is empty.
virtual bool isEmpty() const {return getOctahedronPolygon().isEmpty(
);}
//! Return a point located inside the region.
virtual Vec3d getPointInside() const {return getOctahedronPolygon().
getPointInside();}
//! Return the list of SphericalCap bounding the ConvexPolygon.
virtual QVector<SphericalCap> getBoundingSphericalCaps() const;
//! Return a bounding SphericalCap. This method is heavily used and
therefore needs to be very fast.
//! The returned SphericalCap doesn't have to be the smallest one, b
ut smaller is better.
virtual SphericalCap getBoundingCap() const;
//! Return an enlarged version of this SphericalRegion so that any p
oint distant of more
//! than the given margin now lays within the region.
//! The returned region can be larger than the smallest enlarging re
gion, therefore returning
//! false positive on subsequent intersection tests.
//! The default implementation always return an enlarged bounding Sp
hericalCap.
//! @param margin the minimum enlargement margin in radian.
virtual SphericalRegionP getEnlarged(double margin) const;
//! Return an openGL compatible array to be displayed using vertex a
rrays.
virtual StelVertexArray getFillVertexArray() const {return getOctahe
dronPolygon().getFillVertexArray();}
//! Get the outline of the contours defining the SphericalPolygon.
//! @return a list of vertex which taken 2 by 2 define the contours
of the polygon.
virtual StelVertexArray getOutlineVertexArray() const {return getOct
ahedronPolygon().getOutlineVertexArray();}
//! Serialize the region into a QVariant map matching the JSON forma
t.
virtual QVariantMap toQVariant() const = 0;
//! Serialize the region. This method must allow as fast as possible
serialization and work with deserialize().
virtual void serialize(QDataStream& out) const = 0;
//! Output a JSON string representing the polygon.
//! This method is convenient for debugging.
QByteArray toJSON() const;
//! Returns whether a SphericalRegion is contained into this region.
//! A default potentially very slow implementation is provided for e
ach cases.
bool contains(const SphericalRegion* r) const;
bool contains(const SphericalRegionP r) const {return contains(r.dat
a());}
virtual bool contains(const Vec3d& p) const {return getOctahedronPol
ygon().contains(p);}
virtual bool contains(const SphericalPolygon& r) const;
virtual bool contains(const SphericalConvexPolygon& r) const;
virtual bool contains(const SphericalCap& r) const;
virtual bool contains(const SphericalPoint& r) const;
virtual bool contains(const AllSkySphericalRegion& r) const;
bool contains(const EmptySphericalRegion& r) const {return false;}
//! Returns whether a SphericalRegion intersects with this region.
//! A default potentially very slow implementation is provided for e
ach cases.
bool intersects(const SphericalRegion* r) const;
bool intersects(const SphericalRegionP r) const {return intersects(r
.data());}
bool intersects(const Vec3d& p) const {return contains(p);}
virtual bool intersects(const SphericalPolygon& r) const;
virtual bool intersects(const SphericalConvexPolygon& r) const;
virtual bool intersects(const SphericalCap& r) const;
virtual bool intersects(const SphericalPoint& r) const;
virtual bool intersects(const AllSkySphericalRegion& r) const;
bool intersects(const EmptySphericalRegion& r) const {return false;}
//! Return a new SphericalRegion consisting of the intersection of t
his and the given region.
//! A default potentially very slow implementation is provided for e
ach cases.
SphericalRegionP getIntersection(const SphericalRegion* r) const;
SphericalRegionP getIntersection(const SphericalRegionP r) const {re
turn getIntersection(r.data());}
virtual SphericalRegionP getIntersection(const SphericalPolygon& r)
const;
virtual SphericalRegionP getIntersection(const SphericalConvexPolygo
n& r) const;
virtual SphericalRegionP getIntersection(const SphericalCap& r) cons
t;
virtual SphericalRegionP getIntersection(const SphericalPoint& r) co
nst;
virtual SphericalRegionP getIntersection(const AllSkySphericalRegion
& r) const;
SphericalRegionP getIntersection(const EmptySphericalRegion& r) cons
t;
//! Return a new SphericalRegion consisting of the union of this and
the given region.
//! A default potentially very slow implementation is provided for e
ach cases.
SphericalRegionP getUnion(const SphericalRegion* r) const;
SphericalRegionP getUnion(const SphericalRegionP r) const {return ge
tUnion(r.data());}
virtual SphericalRegionP getUnion(const SphericalPolygon& r) const;
virtual SphericalRegionP getUnion(const SphericalConvexPolygon& r) c
onst;
virtual SphericalRegionP getUnion(const SphericalCap& r) const;
virtual SphericalRegionP getUnion(const SphericalPoint& r) const;
SphericalRegionP getUnion(const AllSkySphericalRegion& r) const;
virtual SphericalRegionP getUnion(const EmptySphericalRegion& r) con
st;
//! Return a new SphericalRegion consisting of the subtraction of th
e given region from this.
//! A default potentially very slow implementation is provided for e
ach cases.
SphericalRegionP getSubtraction(const SphericalRegion* r) const;
SphericalRegionP getSubtraction(const SphericalRegionP r) const {ret
urn getSubtraction(r.data());}
virtual SphericalRegionP getSubtraction(const SphericalPolygon& r) c
onst;
virtual SphericalRegionP getSubtraction(const SphericalConvexPolygon
& r) const;
virtual SphericalRegionP getSubtraction(const SphericalCap& r) const
;
virtual SphericalRegionP getSubtraction(const SphericalPoint& r) con
st;
SphericalRegionP getSubtraction(const AllSkySphericalRegion& r) cons
t;
virtual SphericalRegionP getSubtraction(const EmptySphericalRegion&
r) const;
private:
bool containsDefault(const SphericalRegion* r) const;
bool intersectsDefault(const SphericalRegion* r) const;
SphericalRegionP getIntersectionDefault(const SphericalRegion* r) co
nst;
SphericalRegionP getUnionDefault(const SphericalRegion* r) const;
SphericalRegionP getSubtractionDefault(const SphericalRegion* r) con
st;
}; };
//! @class ConvexPolygon //! @class SphericalCap
//! A special case of ConvexS for which all HalfSpace have an aperture of P //! A SphericalCap is defined by a direction and an aperture.
I/2. //! It forms a cone from the center of the Coordinate frame with a radius d
//! The operator [] behave as for a Polygon, i.e. return the vertex positio .
ns. //! It is a disc on the sphere, a region above a circle on the unit sphere.
//! To acces the HalfSpaces, use the asConvex() method. class SphericalCap : public SphericalRegion
class ConvexPolygon : public ConvexS, public Polygon
{ {
public: public:
//! Construct a SphericalCap with a 90 deg aperture and an undefined
direction.
SphericalCap() : d(0) {;}
//! Default constructor //! Construct a SphericalCap from its direction and assumes a 90 deg
ConvexPolygon() {} aperture.
SphericalCap(double x, double y, double z) : n(x,y,z), d(0) {;}
//! Special constructor for 3 points //! Construct a SphericalCap from its direction and aperture.
ConvexPolygon(const Vec3d &e0,const Vec3d &e1,const Vec3d &e2): //! @param an a unit vector indicating the direction.
ConvexS(e0, e1, e2), Polygon(e0, e1, e2) //! @param ar cosinus of the aperture.
{} SphericalCap(const Vec3d& an, double ar) : n(an), d(ar) {Q_ASSERT(d=
=0 || std::fabs(n.lengthSquared()-1.)<0.0000001);}
//! Special constructor for 4 points
ConvexPolygon(const Vec3d &e0,const Vec3d &e1,const Vec3d &e2, const
Vec3d &e3):
ConvexS(e0, e1, e2, e3), Polygon(e0, e1, e2, e3)
{}
bool operator==(const ConvexPolygon& other) const { //! Copy constructor.
return ((const Polygon&)(*this)==(const Polygon&)other); SphericalCap(const SphericalCap& other) : SphericalRegion(), n(other
} .n), d(other.d) {;}
virtual SphericalRegionType getType() const {return SphericalRegion:
:Cap;}
virtual OctahedronPolygon getOctahedronPolygon() const;
//! Get the area of the intersection of the halfspace on the sphere
in steradian.
virtual double getArea() const {return 2.*M_PI*(1.-d);}
//! By default the [] operator return the vertexes //! Return true if the region is empty.
const Vec3d& operator[](const Polygon::size_type& i)const { virtual bool isEmpty() const {return d>=1.;}
return Polygon::operator[](i);
//! Return a point located inside the SphericalCap.
virtual Vec3d getPointInside() const {return n;}
//! Return itself.
virtual SphericalCap getBoundingCap() const {return *this;}
// Contain and intersect
virtual bool contains(const Vec3d &v) const {Q_ASSERT(d==0 || std::f
abs(v.lengthSquared()-1.)<0.0000001);return (v*n>=d);}
virtual bool contains(const SphericalConvexPolygon& r) const;
virtual bool contains(const SphericalCap& h) const
{
const double a = n*h.n-d*h.d;
return d<=h.d && ( a>=1. || (a>=0. && a*a >= (1.-d*d)*(1.-h.
d*h.d)));
} }
virtual bool contains(const AllSkySphericalRegion& r) const {return
d<=-1;}
virtual bool intersects(const SphericalPolygon& r) const;
virtual bool intersects(const SphericalConvexPolygon& r) const;
//! Returns whether a SphericalCap intersects with this one.
//! I managed to make it without sqrt or acos, so it is very fast!
//! @see http://f4bien.blogspot.com/2009/05/spherical-geometry-optim
isations.html for detailed explanations.
virtual bool intersects(const SphericalCap& h) const
{
const double a = d*h.d - n*h.n;
return d+h.d<=0. || a<=0. || (a<=1. && a*a <= (1.-d*d)*(1.-h
.d*h.d));
}
virtual bool intersects(const AllSkySphericalRegion& poly) const {re
turn d<=1.;}
//! By default the [] operator return the vertexes //! Serialize the region into a QVariant map matching the JSON forma
Vec3d& operator[](Polygon::size_type& i) { t.
return Polygon::operator[](i); //! The format is {"type": "CAP", "center": [ra, dec], "radius": rad
ius}, with ra dec in degree in ICRS frame
//! and radius in degree (between 0 and 180 deg)
virtual QVariantMap toQVariant() const;
virtual void serialize(QDataStream& out) const {out << n << d;}
////////////////////////////////////////////////////////////////////
// Methods specific to SphericalCap
//! Return the radiusof the cap in radian
double getRadius() const {return std::acos(d);}
//! Returns whether a HalfSpace (like a SphericalCap with d=0) inter
sects with this SphericalCap.
//! @param hn0 the x direction of the halfspace.
//! @param hn1 the y direction of the halfspace.
//! @param hn2 the z direction of the halfspace.
inline bool intersectsHalfSpace(double hn0, double hn1, double hn2)
const
{
const double a = n[0]*hn0+n[1]*hn1+n[2]*hn2;
return d<=0. || a<=0. || (a<=1. && a*a <= (1.-d*d));
} }
//! Return the convex polygon area in steradians //! Clip the passed great circle connecting points v1 and v2.
double getArea() const; //! @return true if the great circle intersects with the cap, false
otherwise.
bool clipGreatCircle(Vec3d& v1, Vec3d& v2) const;
//! Return the convex polygon barycenter //! Comparison operator.
Vec3d getBarycenter() const; bool operator==(const SphericalCap& other) const {return (n==other.n
&& d==other.d);}
//! Cast to Polygon in case of ambiguity //! Return the list of closed contours defining the polygon boundari
Polygon& asPolygon() {return static_cast<Polygon&>(*this);} es.
QVector<Vec3d> getClosedOutlineContour() const;
//! Same with const //! Return whether the cap intersect with a convex contour defined b
const Polygon& asPolygon() const {return static_cast<const Polygon&> y nbVertice.
(*this);} bool intersectsConvexContour(const Vec3d* vertice, int nbVertice) co
nst;
//! Cast to Convex in case of ambiguity //! Return whether the cap contains the passed triangle.
ConvexS& asConvex() {return static_cast<ConvexS&>(*this);} bool containsTriangle(const Vec3d* vertice) const;
//! Same with const //! Return whether the cap intersect with the passed triangle.
const ConvexS& asConvex() const {return static_cast<const ConvexS&>( bool intersectsTriangle(const Vec3d* vertice) const;
*this);}
//! Check if the polygon is valid, i.e. it has no side >180 etc //! Deserialize the region. This method must allow as fast as possib
bool checkValid() const; le deserialization.
static SphericalRegionP deserialize(QDataStream& in);
//! Return the relative overlap between the areas of the 2 caps, i.e
:
//! min(intersectionArea/c1.area, intersectionArea/c2.area)
static double relativeAreaOverlap(const SphericalCap& c1, const Sphe
ricalCap& c2);
//! Special case for degenerated polygons (>180 deg), assume full sk //! Return the relative overlap between the diameter of the 2 caps,
y, i.e. intersect and contains is always true. i.e:
static ConvexPolygon fullSky(); //! min(intersectionDistance/c1.diameter, intersectionDistance/c2.di
ameter)
static double relativeDiameterOverlap(const SphericalCap& c1, const
SphericalCap& c2);
//! Compute the intersection of 2 halfspaces on the sphere (usually
on 2 points) and return it in p1 and p2.
//! If the 2 SphericalCap don't intersect or intersect only at 1 poi
nt, false is returned and p1 and p2 are undefined.
static bool intersectionPoints(const SphericalCap& h1, const Spheric
alCap& h2, Vec3d& p1, Vec3d& p2);
//! The direction unit vector. Only if d==0, this vector doesn't nee
d to be unit.
Vec3d n;
//! The cos of cone radius
double d;
}; };
//! We rewrite the intersect for ConvexPolygon //! Return whether the halfspace defined by the vectors v1^v2 and with aper
inline bool intersect(const ConvexPolygon& cp1, const ConvexPolygon& cp2) ture 90 deg contains the point p.
//! The comparison is made with a double number slightly smaller than zero
to avoid floating point precision
//! errors problems (one test fails if it is set to zero).
inline bool sideHalfSpaceContains(const Vec3d& v1, const Vec3d& v2, const V
ec3d& p)
{ {
const ConvexS& c1 = cp1; return (v1[1] * v2[2] - v1[2] * v2[1])*p[0] +
const ConvexS& c2 = cp2; (v1[2] * v2[0] - v1[0] * v2[2])*p[1] +
return !c1.areAllPointsOutsideOneSide(cp2) && !c2.areAllPointsOutsid (v1[0] * v2[1] - v1[1] * v2[0])*p[2]>=-1e-17;
eOneSide(cp1);
} }
//! @class Disk //! Return whether the halfspace defined by the vectors v1 and v2 contains
//! A Disk is defined by a single HalfSpace the SphericalCap h.
struct Disk : HalfSpace inline bool sideHalfSpaceContains(const Vec3d& v1, const Vec3d& v2, const S
{ phericalCap& h)
//! Constructor {
//! @param n a unit vector indicating the the disk center Vec3d n(v1[1]*v2[2]-v1[2]*v2[1], v2[0]*v1[2]-v2[2]*v1[0], v2[1]*v1[0
//! @param r the disk radius in radian ]-v2[0]*v1[1]);
Disk(const Vec3d& an, double r) : HalfSpace(an, std::cos(r)) n.normalize();
{} const double a = n*h.n;
}; return 0<=h.d && ( a>=1. || (a>=0. && a*a >= 1.-h.d*h.d));
}
//! We rewrite the intersect for ConvexPolygon //! Return whether the halfspace defined by the vectors v1 and v2 intersect
inline bool intersect(const ConvexS& cp1, const ConvexPolygon& cp2) s the SphericalCap h.
inline bool sideHalfSpaceIntersects(const Vec3d& v1, const Vec3d& v2, const
SphericalCap& h)
{ {
Q_ASSERT(0); Vec3d n(v1[1]*v2[2]-v1[2]*v2[1], v2[0]*v1[2]-v2[2]*v1[0], v2[1]*v1[0
// TODO ]-v2[0]*v1[1]);
return false; n.normalize();
return h.intersectsHalfSpace(n[0], n[1], n[2]);
} }
template<class S1, class S2> //! @class SphericalPoint
class Difference //! Special SphericalRegion for a point on the sphere.
class SphericalPoint : public SphericalRegion
{ {
public: public:
Difference(const S1& s1_, const S2& s2_) : s1(s1_), s2(s2_) SphericalPoint(const Vec3d& an) : n(an) {Q_ASSERT(std::fabs(1.-n.len
{} gth())<0.0000001);}
virtual ~SphericalPoint() {;}
virtual SphericalRegionType getType() const {return SphericalRegion:
:Point;}
virtual OctahedronPolygon getOctahedronPolygon() const;
virtual double getArea() const {return 0.;}
virtual bool isEmpty() const {return false;}
virtual Vec3d getPointInside() const {return n;}
virtual SphericalCap getBoundingCap() const {return SphericalCap(n,
1);}
//! Serialize the region into a QVariant map matching the JSON forma
t.
//! The format is {"type": "POINT", "pos": [ra, dec]}, with ra dec i
n degree in ICRS frame.
virtual QVariantMap toQVariant() const;
virtual void serialize(QDataStream& out) const {out << n;}
// Contain and intersect
virtual bool contains(const Vec3d& p) const {return n==p;}
virtual bool contains(const SphericalPolygon& r) const {return false
;}
virtual bool contains(const SphericalConvexPolygon& r) const {return
false;}
virtual bool contains(const SphericalCap& c) const {return false;}
virtual bool contains(const SphericalPoint& r) const {return n==r.n;
}
virtual bool contains(const AllSkySphericalRegion& r) const {return
false;}
virtual bool intersects(const SphericalPolygon& r) const;
virtual bool intersects(const SphericalConvexPolygon& r) const;
virtual bool intersects(const SphericalCap& r) const {return r.conta
ins(n);}
virtual bool intersects(const SphericalPoint& r) const {return n==r.
n;}
virtual bool intersects(const AllSkySphericalRegion& r) const {retur
n true;}
S1 s1; //! Deserialize the region. This method must allow as fast as possib
S2 s2; le deserialization.
static SphericalRegionP deserialize(QDataStream& in);
//! The unit vector of the point direction.
Vec3d n;
}; };
template<class S1, class S2, class S> //! @class AllSkySphericalRegion
inline bool intersect(const Difference<S1, S2>& d, const S& s) //! Special SphericalRegion for the whole sphere.
class AllSkySphericalRegion : public SphericalRegion
{ {
return !contains(d.s2, s) && intersect(d.s1, s); public:
} virtual ~AllSkySphericalRegion() {;}
template<class S1, class S2> virtual SphericalRegionType getType() const {return SphericalRegion:
bool intersect(const Difference<S1, S2>& d, const Vec3d& v) :AllSky;}
{ return !contains(d.s2, v) && intersect(d.s1, v); } virtual OctahedronPolygon getOctahedronPolygon() const {return Octah
edronPolygon::getAllSkyOctahedronPolygon();}
virtual double getArea() const {return 4.*M_PI;}
virtual bool isEmpty() const {return false;}
virtual Vec3d getPointInside() const {return Vec3d(1,0,0);}
virtual SphericalCap getBoundingCap() const {return SphericalCap(Vec
3d(1,0,0), -2);}
//! Serialize the region into a QVariant map matching the JSON forma
t.
//! The format is {"type": "ALLSKY"}
virtual QVariantMap toQVariant() const;
virtual void serialize(QDataStream& out) const {;}
// Contain and intersect
virtual bool contains(const Vec3d& p) const {return true;}
virtual bool contains(const SphericalPolygon& r) const {return true;
}
virtual bool contains(const SphericalConvexPolygon& r) const {return
true;}
virtual bool contains(const SphericalCap& r) const {return true;}
virtual bool contains(const SphericalPoint& r) const {return true;}
virtual bool contains(const AllSkySphericalRegion& r) const {return
true;}
virtual bool intersects(const SphericalPolygon& r) const {return tru
e;}
virtual bool intersects(const SphericalConvexPolygon& r) const {retu
rn true;}
virtual bool intersects(const SphericalCap& r) const {return true;}
virtual bool intersects(const SphericalPoint& r) const {return true;
}
virtual bool intersects(const AllSkySphericalRegion& r) const {retur
n true;}
template<class S1, class S2, class S> static const SphericalRegionP staticInstance;
inline bool contains(const Difference<S1, S2>&d, const S& s) };
//! @class AllSkySphericalRegion
//! Special SphericalRegion for the whole sphere.
class EmptySphericalRegion : public SphericalRegion
{ {
return !intersect(d.s2, s) && contains(d.s1, s); public:
} // Avoid name hiding when overloading the virtual methods.
using SphericalRegion::intersects;
using SphericalRegion::contains;
using SphericalRegion::getIntersection;
using SphericalRegion::getUnion;
using SphericalRegion::getSubtraction;
EmptySphericalRegion() {;}
virtual ~EmptySphericalRegion() {;}
virtual SphericalRegionType getType() const {return SphericalRegion:
:Empty;}
virtual OctahedronPolygon getOctahedronPolygon() const {return Octah
edronPolygon::getEmptyOctahedronPolygon();}
virtual double getArea() const {return 0.;}
virtual bool isEmpty() const {return true;}
virtual Vec3d getPointInside() const {return Vec3d(1,0,0);}
virtual SphericalCap getBoundingCap() const {return SphericalCap(Vec
3d(1,0,0), 2);}
//! Serialize the region into a QVariant map matching the JSON forma
t.
//! The format is {"type": "EMPTY"}
virtual QVariantMap toQVariant() const;
virtual void serialize(QDataStream& out) const {;}
// Contain and intersect
virtual bool contains(const Vec3d& p) const {return false;}
virtual bool contains(const SphericalPolygon& r) const {return false
;}
virtual bool contains(const SphericalConvexPolygon& r) const {return
false;}
virtual bool contains(const SphericalCap& r) const {return false;}
virtual bool contains(const SphericalPoint& r) const {return false;}
virtual bool contains(const AllSkySphericalRegion& r) const {return
false;}
virtual bool intersects(const SphericalPolygon& r) const {return fal
se;}
virtual bool intersects(const SphericalConvexPolygon& r) const {retu
rn false;}
virtual bool intersects(const SphericalCap& r) const {return false;}
virtual bool intersects(const SphericalPoint& r) const {return false
;}
virtual bool intersects(const AllSkySphericalRegion& r) const {retur
n false;}
static const SphericalRegionP staticInstance;
};
inline bool contains(const HalfSpace& h, const Vec3d& v) //! @class SphericalPolygonBase
//! Abstract class defining default implementations for some spherical geom
etry methods.
//! All methods are reentrant.
class SphericalPolygon : public SphericalRegion
{ {
return h.contains(v); public:
} // Avoid name hiding when overloading the virtual methods.
using SphericalRegion::intersects;
using SphericalRegion::contains;
using SphericalRegion::getIntersection;
using SphericalRegion::getUnion;
using SphericalRegion::getSubtraction;
SphericalPolygon() {;}
//! Constructor from a list of contours.
SphericalPolygon(const QVector<QVector<Vec3d> >& contours) : octahed
ronPolygon(contours) {;}
//! Constructor from one contour.
SphericalPolygon(const QVector<Vec3d>& contour) : octahedronPolygon(
contour) {;}
SphericalPolygon(const OctahedronPolygon& octContour) : octahedronPo
lygon(octContour) {;}
SphericalPolygon(const QList<OctahedronPolygon>& octContours) : octa
hedronPolygon(octContours) {;}
virtual SphericalRegionType getType() const {return SphericalRegion:
:Polygon;}
virtual OctahedronPolygon getOctahedronPolygon() const {return octah
edronPolygon;}
//! Serialize the region into a QVariant map matching the JSON forma
t.
//! The format is
//! @code {"worldCoords": [[[ra,dec], [ra,dec], [ra,dec], [ra,dec]],
[[ra,dec], [ra,dec], [ra,dec]],[...]]} @endcode
//! worldCoords is a list of closed contours, with each points defin
ed by ra dec in degree in the ICRS frame.
virtual QVariantMap toQVariant() const;
virtual void serialize(QDataStream& out) const;
virtual SphericalCap getBoundingCap() const;
virtual bool contains(const Vec3d& p) const {return octahedronPolygo
n.contains(p);}
virtual bool contains(const SphericalPolygon& r) const {return octah
edronPolygon.contains(r.octahedronPolygon);}
virtual bool contains(const SphericalConvexPolygon& r) const;
virtual bool contains(const SphericalCap& r) const {return octahedro
nPolygon.contains(r.getOctahedronPolygon());}
virtual bool contains(const SphericalPoint& r) const {return octahed
ronPolygon.contains(r.n);}
virtual bool contains(const AllSkySphericalRegion& r) const {return
octahedronPolygon.contains(r.getOctahedronPolygon());}
virtual bool intersects(const SphericalPolygon& r) const {return oct
ahedronPolygon.intersects(r.octahedronPolygon);}
virtual bool intersects(const SphericalConvexPolygon& r) const;
virtual bool intersects(const SphericalCap& r) const {return r.inter
sects(*this);}
virtual bool intersects(const SphericalPoint& r) const {return octah
edronPolygon.contains(r.n);}
virtual bool intersects(const AllSkySphericalRegion& r) const {retur
n !isEmpty();}
virtual SphericalRegionP getIntersection(const SphericalPoint& r) co
nst {return contains(r.n) ? SphericalRegionP(new SphericalPoint(r)) : Empty
SphericalRegion::staticInstance;}
virtual SphericalRegionP getIntersection(const AllSkySphericalRegion
& r) const {return SphericalRegionP(new SphericalPolygon(octahedronPolygon)
);}
virtual SphericalRegionP getUnion(const SphericalPoint& r) const {re
turn SphericalRegionP(new SphericalPolygon(octahedronPolygon));}
virtual SphericalRegionP getUnion(const EmptySphericalRegion& r) con
st {return SphericalRegionP(new SphericalPolygon(octahedronPolygon));}
virtual SphericalRegionP getSubtraction(const SphericalPoint& r) con
st {return SphericalRegionP(new SphericalPolygon(octahedronPolygon));}
virtual SphericalRegionP getSubtraction(const EmptySphericalRegion&
r) const {return SphericalRegionP(new SphericalPolygon(octahedronPolygon));
}
////////////////////////////////////////////////////////////////////
// Methods specific to SphericalPolygon
//! Set the contours defining the SphericalPolygon.
//! @param contours the list of contours defining the polygon area.
The contours are combined using
//! the positive winding rule, meaning that the polygon is the union
of the positive contours minus the negative ones.
void setContours(const QVector<QVector<Vec3d> >& contours) {octahedr
onPolygon = OctahedronPolygon(contours);}
//! Set a single contour defining the SphericalPolygon.
//! @param contours a contour defining the polygon area.
void setContour(const QVector<Vec3d>& contour) {octahedronPolygon =
OctahedronPolygon(contour);}
//! Return the list of closed contours defining the polygon boundari
es.
QVector<QVector<Vec3d> > getClosedOutlineContours() const {Q_ASSERT(
0); return QVector<QVector<Vec3d> >();}
//! Deserialize the region. This method must allow as fast as possib
le deserialization.
static SphericalRegionP deserialize(QDataStream& in);
//! Create a new SphericalRegionP which is the union of all the pass
ed ones.
static SphericalRegionP multiUnion(const QList<SphericalRegionP>& re
gions);
inline bool contains(const HalfSpace& h, const Polygon& poly) private:
OctahedronPolygon octahedronPolygon;
};
//! @class SphericalConvexPolygon
//! A special case of SphericalPolygon for which the polygon is convex.
class SphericalConvexPolygon : public SphericalRegion
{ {
for (Polygon::const_iterator iter=poly.begin();iter!=poly.end();++it public:
er) // Avoid name hiding when overloading the virtual methods.
using SphericalRegion::intersects;
using SphericalRegion::contains;
//! Default constructor.
SphericalConvexPolygon() {;}
//! Constructor from a list of contours.
SphericalConvexPolygon(const QVector<QVector<Vec3d> >& contours) {Q_
ASSERT(contours.size()==1); setContour(contours.at(0));}
//! Constructor from one contour.
SphericalConvexPolygon(const QVector<Vec3d>& contour) {setContour(co
ntour);}
//! Special constructor for triangle.
SphericalConvexPolygon(const Vec3d &e0,const Vec3d &e1,const Vec3d &
e2) {contour << e0 << e1 << e2; updateBoundingCap();}
//! Special constructor for quads.
SphericalConvexPolygon(const Vec3d &e0,const Vec3d &e1,const Vec3d &
e2, const Vec3d &e3) {contour << e0 << e1 << e2 << e3; updateBoundingCap()
;}
virtual SphericalRegionType getType() const {return SphericalRegion:
:ConvexPolygon;}
virtual OctahedronPolygon getOctahedronPolygon() const {return Octah
edronPolygon(contour);}
virtual StelVertexArray getFillVertexArray() const {return StelVerte
xArray(contour, StelVertexArray::TriangleFan);}
virtual StelVertexArray getOutlineVertexArray() const {return StelVe
rtexArray(contour, StelVertexArray::LineLoop);}
virtual double getArea() const;
virtual bool isEmpty() const {return contour.isEmpty();}
virtual Vec3d getPointInside() const;
virtual SphericalCap getBoundingCap() const {return cachedBoundingCa
p;}
QVector<SphericalCap> getBoundingSphericalCaps() const;
//! Serialize the region into a QVariant map matching the JSON forma
t.
//! The format is
//! @code {"type": "CVXPOLYGON", "worldCoords": [[[ra,dec], [ra,dec]
, [ra,dec], [ra,dec]], [[ra,dec], [ra,dec], [ra,dec]],[...]]} @endcode
//! worldCoords is a list of closed contours, with each points defin
ed by ra dec in degree in the ICRS frame.
virtual QVariantMap toQVariant() const;
virtual void serialize(QDataStream& out) const {out << contour;}
// Contain and intersect
virtual bool contains(const Vec3d& p) const;
virtual bool contains(const SphericalPolygon& r) const;
virtual bool contains(const SphericalConvexPolygon& r) const;
virtual bool contains(const SphericalCap& r) const;
virtual bool contains(const SphericalPoint& r) const {return contain
s(r.n);}
virtual bool contains(const AllSkySphericalRegion& r) const {return
false;}
virtual bool intersects(const SphericalCap& r) const {if (!cachedBou
ndingCap.intersects(r)) return false; return r.intersects(*this);}
virtual bool intersects(const SphericalPolygon& r) const;
virtual bool intersects(const SphericalConvexPolygon& r) const;
virtual bool intersects(const SphericalPoint& r) const {return conta
ins(r.n);}
virtual bool intersects(const AllSkySphericalRegion& r) const {retur
n true;}
////////////////////////// TODO
// virtual SphericalRegionP getIntersection(const SphericalPolygon& r)
const;
// virtual SphericalRegionP getIntersection(const SphericalConvexPolygo
n& r) const;
// virtual SphericalRegionP getIntersection(const SphericalCap& r) cons
t;
// virtual SphericalRegionP getIntersection(const SphericalPoint& r) co
nst;
// virtual SphericalRegionP getIntersection(const AllSkySphericalRegion
& r) const;
// virtual SphericalRegionP getUnion(const SphericalPolygon& r) const;
// virtual SphericalRegionP getUnion(const SphericalConvexPolygon& r) c
onst;
// virtual SphericalRegionP getUnion(const SphericalCap& r) const;
// virtual SphericalRegionP getUnion(const SphericalPoint& r) const;
// virtual SphericalRegionP getUnion(const EmptySphericalRegion& r) con
st;
// virtual SphericalRegionP getSubtraction(const SphericalPolygon& r) c
onst;
// virtual SphericalRegionP getSubtraction(const SphericalConvexPolygon
& r) const;
// virtual SphericalRegionP getSubtraction(const SphericalCap& r) const
;
// virtual SphericalRegionP getSubtraction(const SphericalPoint& r) con
st;
// virtual SphericalRegionP getSubtraction(const EmptySphericalRegion&
r) const;
////////////////////////////////////////////////////////////////////
// Methods specific to SphericalConvexPolygon
////////////////////////////////////////////////////////////////////
//! Set a single contour defining the SphericalPolygon.
//! @param acontour a contour defining the polygon area.
void setContour(const QVector<Vec3d>& acontour) {contour=acontour; u
pdateBoundingCap();}
//! Get the single contour defining the SphericalConvexPolygon.
const QVector<Vec3d>& getConvexContour() const {return contour;}
//! Check if the polygon is valid, i.e. it has no side >180.
bool checkValid() const;
//! Check if the passed contour is convex and valid, i.e. it has no
side >180.
static bool checkValidContour(const QVector<Vec3d>& contour);
//! Deserialize the region. This method must allow as fast as possib
le deserialization.
static SphericalRegionP deserialize(QDataStream& in);
protected:
//! A list of vertices of the convex contour.
QVector<Vec3d> contour;
//! Cache the bounding cap.
SphericalCap cachedBoundingCap;
//! Update the bounding cap from the vertex list.
void updateBoundingCap();
//! Computes whether the passed points are all outside of at least o
ne SphericalCap defining the polygon boundary.
//! @param thisContour the vertices defining the contour.
//! @param nbThisContour nb of vertice of the contour.
//! @param points the points to test.
//! @param points the number of points to test.
static bool areAllPointsOutsideOneSide(const Vec3d* thisContour, int
nbThisContour, const Vec3d* points, int nbPoints);
//! Computes whether the passed points are all outside of at least o
ne SphericalCap defining the polygon boundary.
bool areAllPointsOutsideOneSide(const QVector<Vec3d>& points) const
{ {
if (!h.contains(*iter)) return areAllPointsOutsideOneSide(contour.constData(), conto
return false; ur.size(), points.constData(), points.size());
} }
return true;
}
inline bool contains(const ConvexPolygon& c, const Vec3d& v) bool containsConvexContour(const Vec3d* vertice, int nbVertex) const
;
};
//! @class SphericalTexturedPolygon
//! An extension of SphericalPolygon with addition of texture coordinates.
class SphericalTexturedPolygon : public SphericalPolygon
{ {
const ConvexS& conv = c; public:
for (ConvexS::const_iterator iter=conv.begin();iter!=conv.end();++it //! @struct TextureVertex
er) //! A container for 3D vertex + associated texture coordinates
struct TextureVertex
{ {
if (!iter->contains(v)) Vec3d vertex;
return false; Vec2f texCoord;
} };
return true;
} SphericalTexturedPolygon() {;}
//! Constructor from a list of contours.
SphericalTexturedPolygon(const QVector<QVector<TextureVertex> >& con
tours) {Q_ASSERT(0);}
//! Constructor from one contour.
SphericalTexturedPolygon(const QVector<TextureVertex>& contour) {Q_A
SSERT(0);}
//! Return an openGL compatible array of texture coords to be used u
sing vertex arrays.
virtual StelVertexArray getFillVertexArray() const {Q_ASSERT(0); ret
urn StelVertexArray();}
//! Serialize the region into a QVariant map matching the JSON forma
t.
//! The format is:
//! @code {"worldCoords": [[[ra,dec], [ra,dec], [ra,dec], [ra,dec]],
[[ra,dec], [ra,dec], [ra,dec]],[...]],
//! "textureCoords": [[[u,v],[u,v],[u,v],[u,v]], [[u,v],[u,v],[u,v]]
, [...]]}
//! }@endcode
//! textureCoords is a list of texture coordinates in the u,v textur
e space (between 0 and 1).
//! worldCoords is a list of closed contours, with each points defin
ed by ra dec in degree in the ICRS frame.
//! There must be one texture coordinate for each vertex.
virtual QVariantMap toQVariant() const;
virtual void serialize(QDataStream& out) const {Q_ASSERT(0);}
////////////////////////////////////////////////////////////////////
// Methods specific to SphericalTexturedPolygon
//! Set the contours defining the SphericalPolygon.
//! @param contours the list of contours defining the polygon area.
//! @param windingRule the winding rule to use. Default value is Win
dingPositive, meaning that the
//! polygon is the union of the positive contours minus the negative
ones.
void setContours(const QVector<QVector<TextureVertex> >& contours) {
Q_ASSERT(0);}
//! Set a single contour defining the SphericalPolygon.
//! @param contour a contour defining the polygon area.
void setContour(const QVector<TextureVertex>& contour) {Q_ASSERT(0);
}
private:
//! A list of uv textures coordinates corresponding to the triangle
vertices.
//! There should be 1 uv position per vertex.
QVector<Vec2f> textureCoords;
};
inline bool contains(const ConvexPolygon& cp1, const ConvexPolygon& cp2) //! @class SphericalTexturedConvexPolygon
//! Extension of SphericalConvexPolygon for textured polygon.
class SphericalTexturedConvexPolygon : public SphericalConvexPolygon
{ {
const Polygon& poly = cp2; public:
for (Polygon::const_iterator iter=poly.begin();iter!=poly.end();++it //! Default constructor.
er) SphericalTexturedConvexPolygon() {;}
{
if (!contains(cp1, *iter))
return false;
}
return true;
}
//! We rewrite the intersect for Disk/ConvexPolygon //! Constructor from one contour.
//! This method checks that the minimum distance between the Disk center an SphericalTexturedConvexPolygon(const QVector<Vec3d>& contour, const
d each side of the ConvexPolygon QVector<Vec2f>& texCoord) {setContour(contour, texCoord);}
//! is smaller than the disk radius
inline bool intersect(const HalfSpace& h, const ConvexPolygon& cp) //! Special constructor for quads.
{ //! Use the 4 textures corners for the 4 vertices.
if (contains(cp, h.n)) SphericalTexturedConvexPolygon(const Vec3d &e0,const Vec3d &e1,const
return true; Vec3d &e2, const Vec3d &e3) : SphericalConvexPolygon(e0,e1,e2,e3)
const ConvexS& c = cp;
for (ConvexS::const_iterator iter=c.begin();iter!=c.end();++iter)
{ {
const double cosAlpha = h.n*iter->n; textureCoords << Vec2f(0.f, 0.f) << Vec2f(1.f, 0.f) << Vec2f
if (!(std::sqrt(1.-cosAlpha*cosAlpha) > h.d)) (1.f, 1.f) << Vec2f(0.f, 1.f);
return true;
} }
return false;
}
// special for ConvexPolygon //! Return an openGL compatible array to be displayed using vertex a
inline bool intersect(const ConvexPolygon& c, const HalfSpace& h) rrays.
{ //! This method is not optimized for SphericalConvexPolygon instance
return intersect(h, c); s.
} virtual StelVertexArray getFillVertexArray() const {return StelVerte
xArray(contour, StelVertexArray::TriangleFan, textureCoords);}
//! Compute the intersection of 2 halfspaces on the sphere (usually on 2 po
ints) and return it in p1 and p2. //! Set a single contour defining the SphericalPolygon.
//! If the 2 HalfSpace don't interesect or intersect only at 1 point, false //! @param acontour a contour defining the polygon area.
is returned and p1 and p2 are undefined //! @param texCoord a list of texture coordinates matching the verti
bool planeIntersect2(const HalfSpace& h1, const HalfSpace& h2, Vec3d& p1, V ces of the contour.
ec3d& p2); virtual void setContour(const QVector<Vec3d>& acontour, const QVecto
r<Vec2f>& texCoord) {SphericalConvexPolygon::setContour(acontour); textureC
oords=texCoord;}
//! Serialize the region into a QVariant map matching the JSON forma
t.
//! The format is:
//! @code {"type": "CVXPOLYGON", "worldCoords": [[[ra,dec], [ra,dec]
, [ra,dec], [ra,dec]], [[ra,dec], [ra,dec], [ra,dec]],[...]],
//! "textureCoords": [[[u,v],[u,v],[u,v],[u,v]], [[u,v],[u,v],[u,v]]
, [...]]}
//! }@endcode
//! textureCoords is a list of texture coordinates in the u,v textur
e space (between 0 and 1).
//! worldCoords is a list of closed contours, with each points defin
ed by ra dec in degree in the ICRS frame.
//! There must be one texture coordinate for each vertex.
virtual QVariantMap toQVariant() const;
virtual void serialize(QDataStream& out) const {out << contour << te
xtureCoords;}
protected:
//! A list of uv textures coordinates corresponding to the triangle
vertices.
//! There should be 1 uv position per vertex.
QVector<Vec2f> textureCoords;
};
} // namespace StelGeom //! Compute the intersection of 2 great circles segments.
//! @param ok is set to false if no intersection was found.
//! @return the intersection point on the sphere (normalized) if ok is true
, or undefined of ok is false.
Vec3d greatCircleIntersection(const Vec3d& p1, const Vec3d& p2, const Vec3d
& p3, const Vec3d& p4, bool& ok);
//! Compute the intersection of a great circles segment with another great
circle.
//! @param ok is set to false if no intersection was found.
//! @return the intersection point on the sphere (normalized) if ok is true
, or undefined of ok is false.
Vec3d greatCircleIntersection(const Vec3d& p1, const Vec3d& p2, const Vec3d
& nHalfSpace, bool& ok);
#endif // _STELSPHEREGEOMETRY_HPP_ #endif // _STELSPHEREGEOMETRY_HPP_
 End of changes. 54 change blocks. 
237 lines changed or deleted 989 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/