1 /**************************************************************************** 2 ** 3 ** Copyright (c) 2009-2020 C.B. Barber. All rights reserved. 4 ** $Id: //main/2019/qhull/src/libqhullcpp/QhullPoints.h#6 $$Change: 3001 $ 5 ** $DateTime: 2020/07/24 20:43:28 $$Author: bbarber $ 6 ** 7 ****************************************************************************/ 8 9 #ifndef QHULLPOINTS_H 10 #define QHULLPOINTS_H 11 12 #include "libqhull_r/qhull_ra.h" 13 #include "libqhullcpp/QhullPoint.h" 14 15 #include <cstddef> // ptrdiff_t, size_t 16 #include <ostream> 17 18 namespace orgQhull { 19 20 #//!\name Defined here 21 class QhullPoints; //!< One or more points Coordinate pointers with dimension and iterators 22 class QhullPointsIterator; //!< Java-style iterator 23 24 //! QhullPoints are an array of QhullPoint as pointers into an array of coordinates. 25 //! For Qhull/QhullQh, QhullPoints must use hull_dim. Can change QhullPoint to input_dim if needed for Delaunay input site 26 class QhullPoints { 27 28 private: 29 #//!\name Fields 30 coordT * point_first; //!< First coordinate of an array of points of point_dimension 31 coordT * point_end; //!< End of point coordinates (end>=first). Trailing coordinates ignored 32 QhullQh * qh_qh; //!< Maybe initialized NULL to allow ownership by RboxPoints 33 //!< qh_qh used for QhullPoint() and qh_qh->hull_dim in constructor 34 int point_dimension; //!< Dimension, >=0 35 36 public: 37 #//!\name Subtypes 38 class const_iterator; 39 class iterator; 40 typedef QhullPoints::const_iterator ConstIterator; 41 typedef QhullPoints::iterator Iterator; 42 43 #//!\name Construct 44 //! QhullPoint, PointCoordinates, and QhullPoints have similar constructors 45 //! If Qhull/QhullQh is not initialized, then QhullPoints.dimension() is zero unless explicitly set 46 //! Cannot define QhullPoints(int pointDimension) since it is ambiguous with QhullPoints(QhullQh *qqh) QhullPoints()47 QhullPoints() : point_first(0), point_end(0), qh_qh(0), point_dimension(0) { } QhullPoints(int pointDimension,countT coordinateCount2,coordT * c)48 QhullPoints(int pointDimension, countT coordinateCount2, coordT *c) : point_first(c), point_end(c+coordinateCount2), qh_qh(0), point_dimension(pointDimension) { QHULL_ASSERT(pointDimension>=0); } 49 explicit QhullPoints(const Qhull &q); 50 QhullPoints(const Qhull &q, countT coordinateCount2, coordT *c); 51 QhullPoints(const Qhull &q, int pointDimension, countT coordinateCount2, coordT *c); QhullPoints(QhullQh * qqh)52 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)53 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); } 54 QhullPoints(QhullQh *qqh, int pointDimension, countT coordinateCount2, coordT *c); 55 //! Copy constructor copies pointers but not contents. Needed for return by value and parameter passing. QhullPoints(const QhullPoints & other)56 QhullPoints(const QhullPoints &other) : point_first(other.point_first), point_end(other.point_end), qh_qh(other.qh_qh), point_dimension(other.point_dimension) {} 57 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()58 ~QhullPoints() {} 59 60 public: 61 62 #//!\name Conversion 63 64 #ifndef QHULL_NO_STL 65 std::vector<QhullPoint> toStdVector() const; 66 #endif //QHULL_NO_STL 67 #ifdef QHULL_USES_QT 68 QList<QhullPoint> toQList() const; 69 #endif //QHULL_USES_QT 70 71 #//!\name GetSet 72 // Constructs QhullPoint. Cannot return reference. at(countT idx)73 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); return QhullPoint(qh_qh, point_dimension, p); } 74 // Constructs QhullPoint. Cannot return reference. back()75 const QhullPoint back() const { return last(); } back()76 QhullPoint back() { return last(); } begin()77 ConstIterator begin() const { return ConstIterator(*this); } begin()78 Iterator begin() { return Iterator(*this); } constBegin()79 ConstIterator constBegin() const { return ConstIterator(*this); } constData()80 const coordT * constData() const { return point_first; } constEnd()81 ConstIterator constEnd() const { return ConstIterator(qh_qh, point_dimension, point_end); } coordinates()82 coordT * coordinates() const { return point_first; } coordinateCount()83 countT coordinateCount() const { return static_cast<countT>(point_end-point_first); } // WARN64 count()84 countT count() const { return static_cast<countT>(size()); } // WARN64 data()85 const coordT * data() const { return point_first; } data()86 coordT * data() { return point_first; } defineAs(int pointDimension,countT coordinatesCount,coordT * c)87 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; } defineAs(countT coordinatesCount,coordT * c)88 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; } defineAs(const QhullPoints & other)89 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; } dimension()90 int dimension() const { return point_dimension; } end()91 ConstIterator end() const { return ConstIterator(qh_qh, point_dimension, point_end); } end()92 Iterator end() { return Iterator(qh_qh, point_dimension, point_end); } extraCoordinates()93 coordT * extraCoordinates() const { return (extraCoordinatesCount() ? (point_end-extraCoordinatesCount()) : 0); } 94 countT extraCoordinatesCount() const; // WARN64 95 // Constructs QhullPoint. Cannot return reference. first()96 const QhullPoint first() const { return QhullPoint(qh_qh, point_dimension, point_first); } first()97 QhullPoint first() { return QhullPoint(qh_qh, point_dimension, point_first); } 98 // Constructs QhullPoint. Cannot return reference. front()99 const QhullPoint front() const { return first(); } front()100 QhullPoint front() { return first(); } includesCoordinates(const coordT * c)101 bool includesCoordinates(const coordT *c) const { return (c>=point_first && c<point_end); } isEmpty()102 bool isEmpty() const { return (point_end==point_first || point_dimension==0); } 103 // Constructs QhullPoint. Cannot return reference. last()104 const QhullPoint last() const { QHULL_ASSERT(point_first!=0); return QhullPoint(qh_qh, point_dimension, point_end - point_dimension); } last()105 QhullPoint last() { QHULL_ASSERT(point_first!=0); return QhullPoint(qh_qh, point_dimension, point_end - point_dimension); } 106 bool operator==(const QhullPoints &other) const; 107 bool operator!=(const QhullPoints &other) const { return (! operator==(other)); } 108 QhullPoint operator[](countT idx) const { return at(idx); } qh()109 QhullQh * qh() const { return qh_qh; } 110 void resetQhullQh(QhullQh *qqh); setDimension(int d)111 void setDimension(int d) { point_dimension= d; } size()112 size_t size() const { return (point_dimension ? (point_end-point_first)/point_dimension : 0); } 113 QhullPoint value(countT idx) const; 114 QhullPoint value(countT idx, QhullPoint &defaultValue) const; 115 116 #//!\name Methods 117 bool contains(const QhullPoint &t) const; 118 countT count(const QhullPoint &t) const; 119 countT indexOf(const coordT *pointCoordinates) const; 120 countT indexOf(const coordT *pointCoordinates, int noThrow) const; 121 countT indexOf(const QhullPoint &t) const; 122 countT lastIndexOf(const QhullPoint &t) const; 123 //! Returns a subset of the points, not a copy 124 QhullPoints mid(countT idx, countT length= -1) const; 125 126 #//!\name QhullPoints::iterator 127 // Modeled on qlist.h w/o QT_STRICT_ITERATORS 128 // before const_iterator for conversion with comparison operators 129 // See: QhullSet.h 130 class iterator : public QhullPoint { 131 132 public: 133 typedef std::random_access_iterator_tag iterator_category; 134 typedef QhullPoint value_type; 135 typedef value_type * pointer; 136 typedef value_type & reference; 137 typedef ptrdiff_t difference_type; 138 iterator(const QhullPoints & ps)139 explicit iterator(const QhullPoints &ps) : QhullPoint(ps.qh(), ps.dimension(), ps.coordinates()) {} iterator(const int pointDimension,coordT * c)140 iterator(const int pointDimension, coordT *c): QhullPoint(pointDimension, c) {} iterator(const Qhull & q,coordT * c)141 iterator(const Qhull &q, coordT *c): QhullPoint(q, c) {} iterator(const Qhull & q,int pointDimension,coordT * c)142 iterator(const Qhull &q, int pointDimension, coordT *c): QhullPoint(q, pointDimension, c) {} iterator(QhullQh * qqh,coordT * c)143 iterator(QhullQh *qqh, coordT *c): QhullPoint(qqh, c) {} iterator(QhullQh * qqh,int pointDimension,coordT * c)144 iterator(QhullQh *qqh, int pointDimension, coordT *c): QhullPoint(qqh, pointDimension, c) {} iterator(const iterator & other)145 iterator(const iterator &other): QhullPoint(*other) {} 146 iterator & operator=(const iterator &other) { defineAs( const_cast<iterator &>(other)); return *this; } 147 148 // Need 'const QhullPoint' to maintain const 149 const QhullPoint & operator*() const { return *this; } 150 QhullPoint & operator*() { return *this; } 151 const QhullPoint * operator->() const { return this; } 152 QhullPoint * operator->() { return this; } 153 // value instead of reference since advancePoint() modifies self 154 QhullPoint operator[](countT idx) const { QhullPoint result= *this; result.advancePoint(idx); return result; } 155 bool operator==(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates==o.point_coordinates && point_dimension==o.point_dimension); } 156 bool operator!=(const iterator &o) const { return (! operator==(o)); } 157 bool operator<(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates < o.point_coordinates; } 158 bool operator<=(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates <= o.point_coordinates; } 159 bool operator>(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates > o.point_coordinates; } 160 bool operator>=(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates >= o.point_coordinates; } 161 // reinterpret_cast to break circular dependency 162 bool operator==(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return (point_coordinates==reinterpret_cast<const iterator &>(o).point_coordinates && point_dimension==reinterpret_cast<const iterator &>(o).point_dimension); } 163 bool operator!=(const QhullPoints::const_iterator &o) const { return (! operator==(reinterpret_cast<const iterator &>(o))); } 164 bool operator<(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return point_coordinates < reinterpret_cast<const iterator &>(o).point_coordinates; } 165 bool operator<=(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return point_coordinates <= reinterpret_cast<const iterator &>(o).point_coordinates; } 166 bool operator>(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return point_coordinates > reinterpret_cast<const iterator &>(o).point_coordinates; } 167 bool operator>=(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return point_coordinates >= reinterpret_cast<const iterator &>(o).point_coordinates; } 168 iterator & operator++() { advancePoint(1); return *this; } 169 iterator operator++(int) { iterator n= *this; operator++(); return iterator(n); } 170 iterator & operator--() { advancePoint(-1); return *this; } 171 iterator operator--(int) { iterator n= *this; operator--(); return iterator(n); } 172 iterator & operator+=(countT idx) { advancePoint(idx); return *this; } 173 iterator & operator-=(countT idx) { advancePoint(-idx); return *this; } 174 iterator operator+(countT idx) const { iterator n= *this; n.advancePoint(idx); return n; } 175 iterator operator-(countT idx) const { iterator n= *this; n.advancePoint(-idx); return n; } 176 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); } 177 };//QhullPoints::iterator 178 179 #//!\name QhullPoints::const_iterator 180 //!\todo QH11018 FIX: const_iterator same as iterator. SHould have a common definition 181 class const_iterator : public QhullPoint { 182 183 public: 184 typedef std::random_access_iterator_tag iterator_category; 185 typedef QhullPoint value_type; 186 typedef const value_type * pointer; 187 typedef const value_type & reference; 188 typedef ptrdiff_t difference_type; 189 const_iterator(const QhullPoints::iterator & o)190 const_iterator(const QhullPoints::iterator &o) : QhullPoint(*o) {} const_iterator(const QhullPoints & ps)191 explicit const_iterator(const QhullPoints &ps) : QhullPoint(ps.qh(), ps.dimension(), ps.coordinates()) {} const_iterator(const int pointDimension,coordT * c)192 const_iterator(const int pointDimension, coordT *c): QhullPoint(pointDimension, c) {} const_iterator(const Qhull & q,coordT * c)193 const_iterator(const Qhull &q, coordT *c): QhullPoint(q, c) {} const_iterator(const Qhull & q,int pointDimension,coordT * c)194 const_iterator(const Qhull &q, int pointDimension, coordT *c): QhullPoint(q, pointDimension, c) {} const_iterator(QhullQh * qqh,coordT * c)195 const_iterator(QhullQh *qqh, coordT *c): QhullPoint(qqh, c) {} const_iterator(QhullQh * qqh,int pointDimension,coordT * c)196 const_iterator(QhullQh *qqh, int pointDimension, coordT *c): QhullPoint(qqh, pointDimension, c) {} const_iterator(const const_iterator & o)197 const_iterator(const const_iterator &o) : QhullPoint(*o) {} 198 const_iterator &operator=(const const_iterator &o) { defineAs(const_cast<const_iterator &>(o)); return *this; } 199 200 // value/non-const since advancePoint(1), etc. modifies self 201 const QhullPoint & operator*() const { return *this; } 202 const QhullPoint * operator->() const { return this; } 203 // value instead of reference since advancePoint() modifies self 204 const QhullPoint operator[](countT idx) const { QhullPoint n= *this; n.advancePoint(idx); return n; } 205 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); } 206 bool operator!=(const const_iterator &o) const { return (! operator==(o)); } 207 bool operator<(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates < o.point_coordinates); } 208 bool operator<=(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates <= o.point_coordinates); } 209 bool operator>(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates > o.point_coordinates); } 210 bool operator>=(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates >= o.point_coordinates); } 211 const_iterator &operator++() { advancePoint(1); return *this; } 212 const_iterator operator++(int) { const_iterator n= *this; operator++(); return const_iterator(n); } 213 const_iterator &operator--() { advancePoint(-1); return *this; } 214 const_iterator operator--(int) { const_iterator n= *this; operator--(); return const_iterator(n); } 215 const_iterator &operator+=(countT idx) { advancePoint(idx); return *this; } 216 const_iterator &operator-=(countT idx) { advancePoint(-idx); return *this; } 217 const_iterator operator+(countT idx) const { const_iterator n= *this; n.advancePoint(idx); return n; } 218 const_iterator operator-(countT idx) const { const_iterator n= *this; n.advancePoint(-idx); return n; } 219 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); } 220 };//QhullPoints::const_iterator 221 222 #//!\name IO 223 struct PrintPoints{ 224 const QhullPoints *points; 225 const char * point_message; 226 bool with_identifier; PrintPointsPrintPoints227 PrintPoints(const char *message, bool withIdentifier, const QhullPoints &ps) : points(&ps), point_message(message), with_identifier(withIdentifier) {} 228 };//PrintPoints print(const char * message)229 PrintPoints print(const char *message) const { return PrintPoints(message, false, *this); } printWithIdentifier(const char * message)230 PrintPoints printWithIdentifier(const char *message) const { return PrintPoints(message, true, *this); } 231 };//QhullPoints 232 233 234 //! QhullPointsIterator is a Java-style iterator. It may be used on temporary results. It copies the pointers in QhullPoints 235 //! Did not use QHULL_DECLARE_SEQUENTIAL_ITERATOR because next(),etc cannot return a reference to a temporary 236 class QhullPointsIterator 237 { 238 typedef QhullPoints::const_iterator const_iterator; 239 240 #//!\name Fields 241 private: 242 QhullPoints ps; 243 const_iterator i; 244 245 public: QhullPointsIterator(const QhullPoints & other)246 QhullPointsIterator(const QhullPoints &other) : ps(other), i(ps.constBegin()) {} 247 QhullPointsIterator &operator=(const QhullPoints &other) { ps= other; i= ps.constBegin(); return *this; } 248 249 bool findNext(const QhullPoint &t); 250 bool findPrevious(const QhullPoint &t); hasNext()251 bool hasNext() const { return i != ps.constEnd(); } hasPrevious()252 bool hasPrevious() const { return i != ps.constBegin(); } next()253 QhullPoint next() { return *i++; } peekNext()254 QhullPoint peekNext() const { return *i; } peekPrevious()255 QhullPoint peekPrevious() const { const_iterator p= i; return *--p; } previous()256 QhullPoint previous() { return *--i; } toBack()257 void toBack() { i= ps.constEnd(); } toFront()258 void toFront() { i= ps.constBegin(); } 259 };//QhullPointsIterator 260 261 }//namespace orgQhull 262 263 #//!\name Global 264 265 std::ostream & operator<<(std::ostream &os, const orgQhull::QhullPoints &p); 266 std::ostream & operator<<(std::ostream &os, const orgQhull::QhullPoints::PrintPoints &pr); 267 268 #endif // QHULLPOINTS_H 269