54 if (buffer + 8 >
end) {
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)));
75auto getIntersectionBounds(IntersectionRegion
const &compound, F func) {
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) {
174 flatten_operands<UnionRegion>();
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) {
245 bool may_overlap =
false;
247 auto state = operand->overlaps(other);
251 }
if (not state.known()) {
282 flatten_operands<IntersectionRegion>();
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)) {
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) {
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.
CompoundRegion is an intermediate base class for spherical regions that are comprised of a point-set ...
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.
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.
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.
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.