Files
secondo/Algebras/Spatial/CPoint.h

495 lines
11 KiB
C
Raw Normal View History

2026-01-23 17:03:45 +08:00
/*
4 class CPoint
This class implements the memory representation of the ~cpoint~ type
constructor. A cpoint represents a point in the Euclidean plane with a radius
which can be considered as a tolerance value.
The type ~cpoint~ is applied for the types ~cupoint~ and ~cmpoint~.
*/
#ifndef CPOINT_H
#define CPOINT_H
#include <sstream>
#include "Point.h"
class CPoint: public Point {
public:
/*
4.1 Constructors and Destructor
This constructor should not be used:
*/
inline CPoint() {};
/*
There are different ways of constructing a cpoint:
The first one receives a boolean value ~d~ indicating if the point is defined,
two coordinate ~x~ and ~y~ values, and a radius ~r~.
*/
explicit CPoint(const bool d, const Coord x = 0, const Coord y = 0,
const double r = 0.0);
CPoint(const Point& _p, const double _r);
/*
The second one receives a cpoint ~cp~ as argument and creates a cpoint that is a
copy of ~cp~.
*/
CPoint(const CPoint& p);
/*
The destructor.
*/
inline ~CPoint() {}
/*
4.2 Member functions
Returns the ~x~-coordinate. For geographic coordinates: the LONgitude
*/
inline const Coord& GetX() const {
return ((Point*)this)->GetX();
}
/*
Returns the ~y~-coordinate. For geographic coordinates: the LATitude
*/
inline const Coord& GetY() const {
return ((Point*)this)->GetY();
}
/*
Returns the point's bounding box which is a rectangle with (almost)
no extension.
*/
const Rectangle<2> BoundingBox(const Geoid* geoid = 0) const;
void Clear() {} // for compatibility with other spatial objects
/*
Sets the value of the point object.
*/
inline void Set(const bool _defined, const Coord& _x, const Coord _y,
const double _r) {
((Point*)this)->Set(_defined, _x, _y);
radius = _r;
}
void Set(const Coord& x, const Coord& y, const double r);
void Set(const Point& p, const double r);
void Set(const CPoint& p);
/*
Operators redefinition.
*/
CPoint& operator=(const CPoint& cp);
inline bool operator<=(const CPoint& cp) const;
bool operator<(const CPoint& cp) const;
inline bool operator>=(const CPoint& cp) const;
bool operator>(const CPoint& cp) const;
inline CPoint operator+(const CPoint& cp) const;
inline CPoint operator-(const CPoint& cp) const;
inline CPoint operator*(const double d) const;
/*
4.3 Operations
4.3.1 Operation ~scale~
*Precondition:* ~u.IsDefined()~
*Semantics:* $factor * u$
*Complexity:* $O(1)$
*/
inline void Scale(const Coord& factor) {
assert(IsDefined());
((Point*)this)->Scale(factor);
radius *= factor;
}
/*
4.3.1 Operation $=$ (~equal~)
*Precondition:* ~u.IsDefined() $\&\&$ v.IsDefined()~
*Semantics:* $u = v$
*Complexity:* $O(1)$
*/
inline bool operator==(const CPoint& cp) const;
/*
4.3.2 Operation $\neq$ (~not equal~)
*Precondition:* ~u.IsDefined() $\&\&$ v.IsDefined()~
*Semantics:* $u \neq v$
*Complexity:* $O(1)$Algebras/RTree/RTree.examples
*/
inline bool operator!=(const CPoint& cp) const;
/*
4.3.8 Operation ~inside~ (with ~rectangle~)
*Precondition:* ~u.IsDefined()~
*Semantics:* $u \in V$
*Complexity:* $O(1)$
*/
bool Inside(const Rectangle<2>& r, const Geoid* geoid = 0) const;
/*
4.3.13 Operation ~distance~ (with ~cpoint~)
*Precondition:* ~u.IsDefined()~ and ~v.IsDefined()~ and (~geoid == NULL~ or
~geoid.IsDefined()~
*Semantics:* Minimum estimation of distances.
*Complexity:* $O(1)$
*/
double Distance(const CPoint& cp, const Geoid* geoid = 0) const;
/*
4.3.13 Operation ~distance~ (with ~rect2~)
*Precondition:* ~u.IsDefined()~ and ~V.IsOrdered()~ and (~geoid == NULL~ or
~geoid.IsDefined()~
*/
double Distance(const Rectangle<2>& r, const Geoid* geoid = 0) const;
bool Intersects(const Rectangle<2>& r, const Geoid* geoid = 0) const;
/*
4.1 Importz/Export to CSV files
*/
virtual std::string getCsvStr() const {
if (!IsDefined()) {
return "undef";
}
std::stringstream ss;
ss.precision(16);
ss << "(" << ((Point*)this)->getCsvStr() << ", " << radius << ")";
return ss.str();
}
virtual void ReadFromString(std::string value);
/*
4.3.15 Operation ~translate~
This function moves the position of this CPoint object instance.
*/
inline void Translate(const Coord& x, const Coord& y);
inline void Translate(const Coord& x, const Coord& y, CPoint& result) const;
inline void Scale(const Coord& sx, const Coord& sy, const double sr) {
((Point*)this)->Scale(sx, sy);
radius *= sr;
}
inline void Scale(const Coord& sx, const Coord& sy, const double sr,
CPoint& result) const {
result.Set(IsDefined(), x*sx, y*sy, radius*sr);
}
/*
4.3.15 Operation ~rotate~
.
This function rotates this point around the cpoint defined by (x,y)
with a degree of alpha. The result is stored in res.
*/
inline void Rotate(const Coord& x, const Coord& y, const double alpha,
CPoint& res) const;
/*
4.3.15 Operation ~add~
*Precondition:* ~cp1.IsDefined(), cp2.IsDefined()~
*Semantics:* ~(cp1.x + cp2.x, cp1.y + cp2.y), max(cp1.radius, cp2.radius)~
*Complexity:* $O(1)$
*/
inline CPoint Add(const CPoint& p, const Geoid* geoid = 0) const;
inline bool IsEmpty() const {
return ((Point*)this)->IsEmpty();
}
/*
4.3.16 Operation ~toString~
Returns a textual representation of the cpoint. If a ~geoid~ is passed,
data is represented as geographic coordinates. Otherwise, a euclidean
coord-pair string is returned.
*/
std::string toString(const Geoid* geoid = 0) const;
/*
4.3.16 Operation ~GeographicBBox~
Returns the MBR (bounding box) containing the shortest orthodrome path for THIS
Point and the ~other~ Point.
The Geographic MBR is different from the euclidean one, since the orthodrome may
exceed the two points extreme LATitude coordinates.
*/
Rectangle<2> GeographicBBox(const CPoint &other, const Geoid &geoid) const;
/*
4.4 Functions needed to import the the ~cpoint~ data type to tuple
There are totally 8 functions which are defined as virtual functions. They need
to be defined here in order for the CPoint data type to be used in tuple
definition as an attribute.
*/
inline size_t Sizeof() const;
inline size_t HashValue() const {
return (size_t)(((Point*)this)->HashValue() * radius);
}
inline void CopyFrom(const Attribute* right) {
const CPoint* cp = (const CPoint*)right;
SetDefined(cp->IsDefined());
if (IsDefined()) {
Set(cp->x, cp->y, cp->radius);
}
}
inline int Compare(const Attribute *arg) const {
const CPoint* cp = (const CPoint*)arg;
int pointCompare = ((Point*)this)->Compare((Point*)cp);
if (pointCompare != 0) {
return pointCompare;
}
if (radius == cp->radius) {
return 0;
}
return radius > cp->radius ? 1 : -1;
}
inline int CompareAlmost(const Attribute *arg) const {
const CPoint* cp = (const CPoint*)arg;
int pointCompare = ((Point*)this)->CompareAlmost((Point*)cp);
if (pointCompare != 0) {
return pointCompare;
}
if (AlmostEqual(radius, cp->radius)) {
return 0;
}
return radius > cp->radius ? 1 : -1;
}
inline bool Adjacent(const Attribute *arg) const {
return ((Point*)this)->Adjacent(arg);
}
virtual inline CPoint* Clone() const {
return new CPoint(*this);
}
std::ostream& Print(std::ostream &os) const;
virtual bool hasBox() const {
return ((Point*)this)->hasBox();
}
virtual double getMinX() const {
return ((Point*)this)->getMinX();
}
virtual double getMaxX() const {
return ((Point*)this)->getMaxX();
}
virtual double getMinY() const {
return ((Point*)this)->getMinY();
}
virtual double getMaxY() const {
return ((Point*)this)->getMaxY();
}
virtual double getRadius() const {
return radius;
}
static const std::string BasicType() {
return "cpoint";
}
static const bool checkType(const ListExpr type) {
return listutils::isSymbol(type, BasicType());
}
static void* Cast(void* addr) {
return (new (addr)CPoint());
}
protected:
/*
4.5 Attributes
*/
double radius;
/*
The radius.
*/
};
/*
4.6 Auxiliary functions
*/
std::ostream& operator<<(std::ostream& o, const CPoint& p);
inline bool AlmostEqual(const CPoint& cp1, const CPoint& cp2) {
return AlmostEqual(*((Point*)&cp1), *((Point*)&cp2)) &&
AlmostEqual(cp1.getRadius(), cp2.getRadius());
}
/*
11 The inline functions
11.1 Class ~CPoint~
*/
inline CPoint::CPoint(const bool d, const Coord _x, const Coord _y,
const double _r) :
Point(d, _x, _y), radius(_r) {}
inline CPoint::CPoint(const Point& _p, const double _r) :
Point(_p), radius(_r) {}
inline CPoint::CPoint(const CPoint& cp) :
Point(*((Point*)&cp)), radius(cp.getRadius()) {}
inline void CPoint::Set(const Coord& x, const Coord& y, const double r) {
((Point*)this)->Set(x, y);
radius = r;
}
inline void CPoint::Set(const Point& p, const double r) {
((Point*)this)->Set(p);
radius = r;
}
inline void CPoint::Set(const CPoint& cp) {
((Point*)this)->Set(*((Point*)&cp));
radius = cp.getRadius();
}
inline CPoint CPoint::Add(const CPoint& cp, const Geoid* geoid) const {
assert(IsDefined() && cp.IsDefined());
if (!IsDefined() || !cp.IsDefined() || (geoid && !geoid->IsDefined())) {
return CPoint(false, 0.0, 0.0, 0.0);
}
return CPoint(true, x + cp.x, y + cp.y, std::max(radius, cp.radius));
}
inline CPoint& CPoint::operator=(const CPoint& cp) {
*((Point*)this) = (*((Point*)&cp));
radius = cp.getRadius();
return *this;
}
inline bool CPoint::operator==(const CPoint& cp) const {
if (*((Point*)this) == (*((Point*)&cp))) {
if (!IsDefined() && !cp.IsDefined()){
return true;
}
return AlmostEqual(radius, cp.getRadius());
}
return false;
}
inline bool CPoint::operator!=(const CPoint& cp) const {
return !(*this == cp);
}
inline bool CPoint::operator<=(const CPoint& cp) const {
return !(*this > cp);
}
inline bool CPoint::operator<(const CPoint& cp) const {
return *((Point*)this) < (*((Point*)&cp));
}
inline bool CPoint::operator>=(const CPoint& cp) const {
return !(*this < cp);
}
inline bool CPoint::operator>(const CPoint& cp) const {
return *((Point*)this) > (*((Point*)&cp));
}
inline CPoint CPoint::operator+(const CPoint& cp) const {
return CPoint((IsDefined() && cp.IsDefined()), x + cp.x, y + cp.y,
std::max(radius, cp.getRadius()));
}
inline CPoint CPoint::operator-(const CPoint& cp) const {
return CPoint((IsDefined() && cp.IsDefined()), x - cp.x, y - cp.y,
std::min(radius, cp.getRadius()));
}
inline CPoint CPoint::operator*(const double d) const {
return CPoint(IsDefined(), x * d, y * d , radius * d);
}
inline size_t CPoint::Sizeof() const {
return sizeof(*this);
}
inline void CPoint::Translate(const Coord& x, const Coord& y) {
((Point*)this)->Translate(x, y);
}
inline void CPoint::Translate(const Coord& tx, const Coord& ty, CPoint& res)
const {
res.Set(IsDefined(), x + tx, y + ty, radius);
}
#endif