49char const *
const FOUND_ANTIPODAL_POINT =
50 "The convex hull of the given point set is the "
53char const *
const NOT_ENOUGH_POINTS =
54 "The convex hull of a point set containing less than "
55 "3 distinct, non-coplanar points is not a convex polygon";
62std::vector<UnitVector3d>::iterator findPlane(
69 UnitVector3d & v0 = points[0];
70 UnitVector3d & v1 = points[1];
71 std::vector<UnitVector3d>::iterator
const end = points.
end();
72 std::vector<UnitVector3d>::iterator v = points.
begin() + 1;
73 for (; v !=
end; ++v) {
93std::vector<UnitVector3d>::iterator findTriangle(
96 std::vector<UnitVector3d>::iterator v = findPlane(points);
97 std::vector<UnitVector3d>::iterator
const end = points.
end();
98 UnitVector3d & v0 = points[0];
99 UnitVector3d & v1 = points[1];
103 UnitVector3d n(v0.robustCross(v1));
104 for (; v !=
end; ++v) {
109 }
else if (ccw < 0) {
116 if (*v == v0 || *v == v1) {
119 if (*v == -v0 || *v == -v1) {
153 typedef std::vector<UnitVector3d>::iterator VertexIterator;
154 VertexIterator hullEnd = points.
begin() + 3;
155 VertexIterator
const end = points.
end();
157 for (VertexIterator v = findTriangle(points); v !=
end; ++v) {
172 VertexIterator i = hullEnd - 1;
173 VertexIterator j = points.
begin();
176 VertexIterator toCCW = hullEnd;
180 VertexIterator fromCCW = hullEnd;
184 bool prevCCW = firstCCW;
188 for (i = j, ++j; j != hullEnd; i = j, ++j) {
194 }
else if (prevCCW) {
205 }
else if (prevCCW) {
206 fromCCW = points.
begin();
210 if (toCCW == hullEnd) {
222 if (toCCW < fromCCW) {
223 if (toCCW != points.
begin()) {
228 }
else if (toCCW > fromCCW) {
230 if (toCCW != fromCCW) {
231 hullEnd =
std::copy(toCCW, hullEnd, fromCCW);
234 if (fromCCW == points.
begin()) {
265 computeHull(_vertices);
272 if (_vertices.size() != p._vertices.size()) {
275 VertexIterator i = _vertices.begin();
276 VertexIterator f = p._vertices.begin();
277 VertexIterator
const ep = p._vertices.end();
279 for (; f != ep; ++f) {
290 for (VertexIterator j = f + 1; j != ep; ++i, ++j) {
295 for (VertexIterator j = p._vertices.begin(); j != f; ++i, ++j) {
324 return (
relate(r) & CONTAINS) != 0;
328 return (
relate(r) & DISJOINT) != 0;
336 return (
relate(r) & WITHIN) != 0;
358 buffer.
reserve(1 + 24 * _vertices.size());
371 if (buffer ==
nullptr || *buffer !=
TYPE_CODE ||
372 n < 1 + 24*3 || (n - 1) % 24 != 0) {
377 size_t nv = (n - 1) / 24;
378 poly->_vertices.reserve(nv);
379 for (
size_t i = 0; i < nv; ++i, buffer += 24) {
390 typedef std::vector<UnitVector3d>::const_iterator VertexIterator;
393 os <<
"{\"ConvexPolygon\": [" << *v;
394 for (++v; v !=
end; ++v) { os <<
", " << *v; }
This file declares a class for representing convex polygons with great circle edges on the unit spher...
This file contains the meat of the ConvexPolygon implementation.
Box3d represents a box in ℝ³.
Box represents a rectangle in spherical coordinate space that contains its boundary.
Circle is a circular region on the unit sphere that contains its boundary.
ConvexPolygon is a closed convex polygon on the unit sphere.
Box3d getBoundingBox3d() const override
getBoundingBox3d returns a 3-dimensional bounding-box for this region.
bool intersects(Region const &r) const
UnitVector3d getCentroid() const
The centroid of a polygon is its center of mass projected onto S², assuming a uniform mass distributi...
bool contains(UnitVector3d const &v) const override
bool isDisjointFrom(Region const &r) const
Relationship relate(Region const &r) const override
Circle getBoundingCircle() const override
getBoundingCircle returns a bounding-circle for this region.
std::vector< uint8_t > encode() const override
encode serializes this region into an opaque byte string.
static constexpr uint8_t TYPE_CODE
Box getBoundingBox() const override
getBoundingBox returns a bounding-box for this region.
static std::unique_ptr< ConvexPolygon > decode(std::vector< uint8_t > const &s)
bool operator==(ConvexPolygon const &p) const
Two convex polygons are equal iff they contain the same points.
std::vector< UnitVector3d > const & getVertices() const
bool isWithin(Region const &r) const
Ellipse is an elliptical region on the sphere.
Region is a minimal interface for 2-dimensional regions on the unit sphere.
UnitVector3d is a unit vector in ℝ³ with components stored in double precision.
static UnitVector3d fromNormalized(Vector3d const &v)
fromNormalized returns the unit vector equal to v, which is assumed to be normalized.
This file contains simple helper functions for encoding and decoding primitive types to/from byte str...
T copy_backward(T... args)
Low-level polynomials (including special polynomials) in C++.
bool contains(VertexIterator const begin, VertexIterator const end, UnitVector3d const &v)
Circle boundingCircle(VertexIterator const begin, VertexIterator const end)
Box3d boundingBox3d(VertexIterator const begin, VertexIterator const end)
UnitVector3d centroid(VertexIterator const begin, VertexIterator const end)
Relationship relate(VertexIterator const begin, VertexIterator const end, Box const &b)
Box boundingBox(VertexIterator const begin, VertexIterator const end)
void encodeDouble(double item, std::vector< uint8_t > &buffer)
encodeDouble appends an IEEE double in little-endian byte order to the end of buffer.
std::ostream & operator<<(std::ostream &, Angle const &)
int orientation(UnitVector3d const &a, UnitVector3d const &b, UnitVector3d const &c)
orientation computes and returns the orientations of 3 unit vectors a, b and c.
double decodeDouble(uint8_t const *buffer)
decodeDouble extracts an IEEE double from the 8 byte little-endian byte sequence in buffer.
This file declares functions for orienting points on the sphere.