/**************************************************************************** ** ** Copyright (c) 2009-2020 C.B. Barber. All rights reserved. ** $Id: //main/2019/qhull/src/libqhullcpp/QhullPoints.h#6 $$Change: 3001 $ ** $DateTime: 2020/07/24 20:43:28 $$Author: bbarber $ ** ****************************************************************************/ #ifndef QHULLPOINTS_H #define QHULLPOINTS_H #include "libqhull_r/qhull_ra.h" #include "libqhullcpp/QhullPoint.h" #include // ptrdiff_t, size_t #include namespace orgQhull { #//!\name Defined here class QhullPoints; //!< One or more points Coordinate pointers with dimension and iterators class QhullPointsIterator; //!< Java-style iterator //! QhullPoints are an array of QhullPoint as pointers into an array of coordinates. //! For Qhull/QhullQh, QhullPoints must use hull_dim. Can change QhullPoint to input_dim if needed for Delaunay input site class QhullPoints { private: #//!\name Fields coordT * point_first; //!< First coordinate of an array of points of point_dimension coordT * point_end; //!< End of point coordinates (end>=first). Trailing coordinates ignored QhullQh * qh_qh; //!< Maybe initialized NULL to allow ownership by RboxPoints //!< qh_qh used for QhullPoint() and qh_qh->hull_dim in constructor int point_dimension; //!< Dimension, >=0 public: #//!\name Subtypes class const_iterator; class iterator; typedef QhullPoints::const_iterator ConstIterator; typedef QhullPoints::iterator Iterator; #//!\name Construct //! QhullPoint, PointCoordinates, and QhullPoints have similar constructors //! If Qhull/QhullQh is not initialized, then QhullPoints.dimension() is zero unless explicitly set //! Cannot define QhullPoints(int pointDimension) since it is ambiguous with QhullPoints(QhullQh *qqh) QhullPoints() : point_first(0), point_end(0), qh_qh(0), point_dimension(0) { } QhullPoints(int pointDimension, countT coordinateCount2, coordT *c) : point_first(c), point_end(c+coordinateCount2), qh_qh(0), point_dimension(pointDimension) { QHULL_ASSERT(pointDimension>=0); } explicit QhullPoints(const Qhull &q); QhullPoints(const Qhull &q, countT coordinateCount2, coordT *c); QhullPoints(const Qhull &q, int pointDimension, countT coordinateCount2, coordT *c); explicit QhullPoints(QhullQh *qqh) : point_first(0), point_end(0), qh_qh(qqh), point_dimension(qqh ? qqh->hull_dim : 0) { } QhullPoints(QhullQh *qqh, countT coordinateCount2, coordT *c) : point_first(c), point_end(c+coordinateCount2), qh_qh(qqh), point_dimension(qqh ? qqh->hull_dim : 0) { QHULL_ASSERT(qqh && qqh->hull_dim>0); } QhullPoints(QhullQh *qqh, int pointDimension, countT coordinateCount2, coordT *c); //! Copy constructor copies pointers but not contents. Needed for return by value and parameter passing. QhullPoints(const QhullPoints &other) : point_first(other.point_first), point_end(other.point_end), qh_qh(other.qh_qh), point_dimension(other.point_dimension) {} QhullPoints & operator=(const QhullPoints &other) { point_first= other.point_first; point_end= other.point_end; qh_qh= other.qh_qh; point_dimension= other.point_dimension; return *this; } ~QhullPoints() {} public: #//!\name Conversion #ifndef QHULL_NO_STL std::vector toStdVector() const; #endif //QHULL_NO_STL #ifdef QHULL_USES_QT QList toQList() const; #endif //QHULL_USES_QT #//!\name GetSet // Constructs QhullPoint. Cannot return reference. const QhullPoint at(countT idx) const { /* point_first==0 caught by point_end assert */ coordT *p= point_first+idx*point_dimension; QHULL_ASSERT(p(point_end-point_first); } // WARN64 countT count() const { return static_cast(size()); } // WARN64 const coordT * data() const { return point_first; } coordT * data() { return point_first; } void defineAs(int pointDimension, countT coordinatesCount, coordT *c) { QHULL_ASSERT(pointDimension>=0 && coordinatesCount>=0 && c!=0); point_first= c; point_end= c+coordinatesCount; point_dimension= pointDimension; } void defineAs(countT coordinatesCount, coordT *c) { QHULL_ASSERT((point_dimension>0 && coordinatesCount>=0 && c!=0) || (c==0 && coordinatesCount==0)); point_first= c; point_end= c+coordinatesCount; } void defineAs(const QhullPoints &other) { point_first= other.point_first; point_end= other.point_end; qh_qh= other.qh_qh; point_dimension= other.point_dimension; } int dimension() const { return point_dimension; } ConstIterator end() const { return ConstIterator(qh_qh, point_dimension, point_end); } Iterator end() { return Iterator(qh_qh, point_dimension, point_end); } coordT * extraCoordinates() const { return (extraCoordinatesCount() ? (point_end-extraCoordinatesCount()) : 0); } countT extraCoordinatesCount() const; // WARN64 // Constructs QhullPoint. Cannot return reference. const QhullPoint first() const { return QhullPoint(qh_qh, point_dimension, point_first); } QhullPoint first() { return QhullPoint(qh_qh, point_dimension, point_first); } // Constructs QhullPoint. Cannot return reference. const QhullPoint front() const { return first(); } QhullPoint front() { return first(); } bool includesCoordinates(const coordT *c) const { return (c>=point_first && c(other)); return *this; } // Need 'const QhullPoint' to maintain const const QhullPoint & operator*() const { return *this; } QhullPoint & operator*() { return *this; } const QhullPoint * operator->() const { return this; } QhullPoint * operator->() { return this; } // value instead of reference since advancePoint() modifies self QhullPoint operator[](countT idx) const { QhullPoint result= *this; result.advancePoint(idx); return result; } bool operator==(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates==o.point_coordinates && point_dimension==o.point_dimension); } bool operator!=(const iterator &o) const { return (! operator==(o)); } bool operator<(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates < o.point_coordinates; } bool operator<=(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates <= o.point_coordinates; } bool operator>(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates > o.point_coordinates; } bool operator>=(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates >= o.point_coordinates; } // reinterpret_cast to break circular dependency bool operator==(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast(o).qh_qh); return (point_coordinates==reinterpret_cast(o).point_coordinates && point_dimension==reinterpret_cast(o).point_dimension); } bool operator!=(const QhullPoints::const_iterator &o) const { return (! operator==(reinterpret_cast(o))); } bool operator<(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast(o).qh_qh); return point_coordinates < reinterpret_cast(o).point_coordinates; } bool operator<=(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast(o).qh_qh); return point_coordinates <= reinterpret_cast(o).point_coordinates; } bool operator>(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast(o).qh_qh); return point_coordinates > reinterpret_cast(o).point_coordinates; } bool operator>=(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast(o).qh_qh); return point_coordinates >= reinterpret_cast(o).point_coordinates; } iterator & operator++() { advancePoint(1); return *this; } iterator operator++(int) { iterator n= *this; operator++(); return iterator(n); } iterator & operator--() { advancePoint(-1); return *this; } iterator operator--(int) { iterator n= *this; operator--(); return iterator(n); } iterator & operator+=(countT idx) { advancePoint(idx); return *this; } iterator & operator-=(countT idx) { advancePoint(-idx); return *this; } iterator operator+(countT idx) const { iterator n= *this; n.advancePoint(idx); return n; } iterator operator-(countT idx) const { iterator n= *this; n.advancePoint(-idx); return n; } difference_type operator-(iterator o) const { QHULL_ASSERT(qh_qh==o.qh_qh && point_dimension==o.point_dimension); return (point_dimension ? (point_coordinates-o.point_coordinates)/point_dimension : 0); } };//QhullPoints::iterator #//!\name QhullPoints::const_iterator //!\todo QH11018 FIX: const_iterator same as iterator. SHould have a common definition class const_iterator : public QhullPoint { public: typedef std::random_access_iterator_tag iterator_category; typedef QhullPoint value_type; typedef const value_type * pointer; typedef const value_type & reference; typedef ptrdiff_t difference_type; const_iterator(const QhullPoints::iterator &o) : QhullPoint(*o) {} explicit const_iterator(const QhullPoints &ps) : QhullPoint(ps.qh(), ps.dimension(), ps.coordinates()) {} const_iterator(const int pointDimension, coordT *c): QhullPoint(pointDimension, c) {} const_iterator(const Qhull &q, coordT *c): QhullPoint(q, c) {} const_iterator(const Qhull &q, int pointDimension, coordT *c): QhullPoint(q, pointDimension, c) {} const_iterator(QhullQh *qqh, coordT *c): QhullPoint(qqh, c) {} const_iterator(QhullQh *qqh, int pointDimension, coordT *c): QhullPoint(qqh, pointDimension, c) {} const_iterator(const const_iterator &o) : QhullPoint(*o) {} const_iterator &operator=(const const_iterator &o) { defineAs(const_cast(o)); return *this; } // value/non-const since advancePoint(1), etc. modifies self const QhullPoint & operator*() const { return *this; } const QhullPoint * operator->() const { return this; } // value instead of reference since advancePoint() modifies self const QhullPoint operator[](countT idx) const { QhullPoint n= *this; n.advancePoint(idx); return n; } bool operator==(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates == o.point_coordinates && point_dimension==o.point_dimension); } bool operator!=(const const_iterator &o) const { return (! operator==(o)); } bool operator<(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates < o.point_coordinates); } bool operator<=(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates <= o.point_coordinates); } bool operator>(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates > o.point_coordinates); } bool operator>=(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates >= o.point_coordinates); } const_iterator &operator++() { advancePoint(1); return *this; } const_iterator operator++(int) { const_iterator n= *this; operator++(); return const_iterator(n); } const_iterator &operator--() { advancePoint(-1); return *this; } const_iterator operator--(int) { const_iterator n= *this; operator--(); return const_iterator(n); } const_iterator &operator+=(countT idx) { advancePoint(idx); return *this; } const_iterator &operator-=(countT idx) { advancePoint(-idx); return *this; } const_iterator operator+(countT idx) const { const_iterator n= *this; n.advancePoint(idx); return n; } const_iterator operator-(countT idx) const { const_iterator n= *this; n.advancePoint(-idx); return n; } difference_type operator-(const_iterator o) const { QHULL_ASSERT(qh_qh==o.qh_qh && point_dimension==o.point_dimension); return (point_dimension ? (point_coordinates-o.point_coordinates)/point_dimension : 0); } };//QhullPoints::const_iterator #//!\name IO struct PrintPoints{ const QhullPoints *points; const char * point_message; bool with_identifier; PrintPoints(const char *message, bool withIdentifier, const QhullPoints &ps) : points(&ps), point_message(message), with_identifier(withIdentifier) {} };//PrintPoints PrintPoints print(const char *message) const { return PrintPoints(message, false, *this); } PrintPoints printWithIdentifier(const char *message) const { return PrintPoints(message, true, *this); } };//QhullPoints //! QhullPointsIterator is a Java-style iterator. It may be used on temporary results. It copies the pointers in QhullPoints //! Did not use QHULL_DECLARE_SEQUENTIAL_ITERATOR because next(),etc cannot return a reference to a temporary class QhullPointsIterator { typedef QhullPoints::const_iterator const_iterator; #//!\name Fields private: QhullPoints ps; const_iterator i; public: QhullPointsIterator(const QhullPoints &other) : ps(other), i(ps.constBegin()) {} QhullPointsIterator &operator=(const QhullPoints &other) { ps= other; i= ps.constBegin(); return *this; } bool findNext(const QhullPoint &t); bool findPrevious(const QhullPoint &t); bool hasNext() const { return i != ps.constEnd(); } bool hasPrevious() const { return i != ps.constBegin(); } QhullPoint next() { return *i++; } QhullPoint peekNext() const { return *i; } QhullPoint peekPrevious() const { const_iterator p= i; return *--p; } QhullPoint previous() { return *--i; } void toBack() { i= ps.constEnd(); } void toFront() { i= ps.constBegin(); } };//QhullPointsIterator }//namespace orgQhull #//!\name Global std::ostream & operator<<(std::ostream &os, const orgQhull::QhullPoints &p); std::ostream & operator<<(std::ostream &os, const orgQhull::QhullPoints::PrintPoints &pr); #endif // QHULLPOINTS_H