53std::uint64_t consumeDecodeU64(std::uint8_t
const *&buffer, std::uint8_t
const *end) {
54 if (buffer + 8 > end) {
55 throw std::runtime_error(
"Encoded CompoundRegion is truncated.");
63auto getUnionBounds(
UnionRegion const &compound, F func) {
64 if (compound.nOperands() == 0) {
67 auto bounds = func(compound.getOperand(0));
68 for (
std::size_t i = 1; i < compound.nOperands(); ++ i) {
69 bounds.expandTo(func(compound.getOperand(i)));
76 if (compound.nOperands() == 0) {
79 auto bounds = func(compound.getOperand(0));
80 for (
std::size_t i = 1; i < compound.nOperands(); ++ i) {
81 bounds.clipTo(func(compound.getOperand(i)));
96 for (
auto&& operand: other._operands) {
97 _operands.emplace_back(operand->clone());
102template <
typename Compound>
104 for (
size_t i = 0; i != _operands.size(); ) {
105 if (
auto compound =
dynamic_cast<Compound*
>(_operands[i].get())) {
108 compound->_operands.begin(),
109 compound->_operands.end(),
112 _operands.erase(_operands.begin() + i);
127 for (
auto&& operand: _operands) {
128 auto operand_buffer = operand->encode();
129 encodeU64(operand_buffer.size(), buffer);
130 buffer.
insert(buffer.
end(), operand_buffer.begin(), operand_buffer.end());
141 if (buffer[0] != tc) {
146 while (buffer != end) {
148 if (buffer + nBytes > end) {
180 if (not operand->isEmpty()) {
188 return getUnionBounds(*
this, [](
Region const &r) {
return r.getBoundingBox(); });
192 return getUnionBounds(*
this, [](
Region const &r) {
return r.getBoundingBox3d(); });
196 return getUnionBounds(*
this, [](
Region const &r) {
return r.getBoundingCircle(); });
201 if (operand->contains(v)) {
212 auto result = DISJOINT | WITHIN;
214 auto const stop = CONTAINS;
216 auto rel = operand->relate(rhs);
219 if ((rel & DISJOINT) != DISJOINT) {
224 if ((rel & WITHIN) != WITHIN) {
228 if ((rel & CONTAINS) == CONTAINS) {
231 if (result == stop) {
245 bool may_overlap =
false;
247 auto state = operand->overlaps(other);
251 }
if (not state.known()) {
293 operands().begin(),
operands().end(), [](
auto const& operand) {
return operand->isEmpty(); }
300 for (
auto op1 = begin; op1 != end; ++ op1) {
301 for (
auto op2 = op1 + 1; op2 != end; ++ op2) {
302 if ((*op1)->overlaps(**op2) ==
false) {
312 return getIntersectionBounds(*
this, [](
Region const &r) {
return r.getBoundingBox(); });
316 return getIntersectionBounds(*
this, [](
Region const &r) {
return r.getBoundingBox3d(); });
320 return getIntersectionBounds(*
this, [](
Region const &r) {
return r.getBoundingCircle(); });
325 if (not operand->contains(v)) {
333 auto result = CONTAINS;
335 auto const stop = DISJOINT | WITHIN;
337 auto rel = operand->relate(rhs);
340 if ((rel & CONTAINS) != CONTAINS) {
345 if ((rel & DISJOINT) == DISJOINT) {
350 if ((rel & WITHIN) == WITHIN) {
353 if (result == stop) {
373 auto state = operand->overlaps(other);
374 if (state ==
false) {
This file declares a class for representing axis-aligned bounding boxes in ℝ³.
This file declares a class for representing circular regions on the unit sphere.
This file declares classes for representing compound regions on the unit sphere.
This file declares a class for representing convex polygons with great circle edges on the unit spher...
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.
virtual Relationship relate(Region const &r) const =0
std::vector< std::unique_ptr< Region > > const & operands() const
std::vector< std::uint8_t > _encode(std::uint8_t tc) const
CompoundRegion(std::vector< std::unique_ptr< Region > > operands) noexcept
Construct by taking ownership of operands.
static std::unique_ptr< CompoundRegion > decode(std::vector< std::uint8_t > const &s)
static std::vector< std::unique_ptr< Region > > _decode(std::uint8_t tc, std::uint8_t const *buffer, std::size_t nBytes)
ConvexPolygon is a closed convex polygon on the unit sphere.
Ellipse is an elliptical region on the sphere.
IntersectionRegion is a lazy point-set inersection of its operands.
Relationship relate(Region const &r) const override
IntersectionRegion(std::vector< std::unique_ptr< Region > > operands)
Construct by taking ownership of operands.
static std::unique_ptr< IntersectionRegion > decode(std::vector< std::uint8_t > const &s)
static constexpr std::uint8_t TYPE_CODE
Circle getBoundingCircle() const override
getBoundingCircle returns a bounding-circle for this region.
bool isEmpty() const override
isEmpty returns true when a region does not contain any points.
Box3d getBoundingBox3d() const override
getBoundingBox3d returns a 3-dimensional bounding-box for this region.
bool contains(UnitVector3d const &v) const override
contains tests whether the given unit vector is inside this region.
Box getBoundingBox() const override
getBoundingBox returns a bounding-box for this region.
TriState overlaps(Region const &other) const override
Region is a minimal interface for 2-dimensional regions on the unit sphere.
static std::unique_ptr< Region > decode(std::vector< std::uint8_t > const &s)
virtual bool isEmpty() const =0
isEmpty returns true when a region does not contain any points.
TriState represents a boolean value with additional unknown state.
UnionRegion is a lazy point-set union of its operands.
Box getBoundingBox() const override
getBoundingBox returns a bounding-box for this region.
static constexpr std::uint8_t TYPE_CODE
TriState overlaps(Region const &other) const override
bool isEmpty() const override
isEmpty returns true when a region does not contain any points.
Relationship relate(Region const &r) const override
bool contains(UnitVector3d const &v) const override
contains tests whether the given unit vector is inside this region.
UnionRegion(std::vector< std::unique_ptr< Region > > operands)
Construct by taking ownership of operands.
Circle getBoundingCircle() const override
getBoundingCircle returns a bounding-circle for this region.
static std::unique_ptr< UnionRegion > decode(std::vector< std::uint8_t > const &s)
Box3d getBoundingBox3d() const override
getBoundingBox3d returns a 3-dimensional bounding-box for this region.
UnitVector3d is a unit vector in ℝ³ with components stored in double precision.
This file contains simple helper functions for encoding and decoding primitive types to/from byte str...
std::uint64_t decodeU64(std::uint8_t const *buffer)
decodeU64 extracts an uint64 from the 8 byte little-endian byte sequence in buffer.
void encodeU64(std::uint64_t item, std::vector< std::uint8_t > &buffer)
encodeU64 appends an uint64 in little-endian byte order to the end of buffer.
std::bitset< 3 > Relationship
Relationship describes how two sets are related.
decltype(sizeof(void *)) size_t
This file declares a class for representing longitude/latitude angle boxes on the unit sphere.
This file declares a class for representing elliptical regions on the unit sphere.