Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:01:56

0001 /****************************************************************************
0002 **
0003 ** Copyright (c) 2009-2020 C.B. Barber. All rights reserved.
0004 ** $Id: //main/2019/qhull/src/libqhullcpp/QhullPoints.h#6 $$Change: 3001 $
0005 ** $DateTime: 2020/07/24 20:43:28 $$Author: bbarber $
0006 **
0007 ****************************************************************************/
0008 
0009 #ifndef QHULLPOINTS_H
0010 #define QHULLPOINTS_H
0011 
0012 #include "libqhull_r/qhull_ra.h"
0013 #include "libqhullcpp/QhullPoint.h"
0014 
0015 #include <cstddef>  // ptrdiff_t, size_t
0016 #include <ostream>
0017 
0018 namespace orgQhull {
0019 
0020 #//!\name Defined here
0021     class QhullPoints;          //!< One or more points Coordinate pointers with dimension and iterators
0022     class QhullPointsIterator;  //!< Java-style iterator
0023 
0024 //! QhullPoints are an array of QhullPoint as pointers into an array of coordinates.
0025 //! For Qhull/QhullQh, QhullPoints must use hull_dim.  Can change QhullPoint to input_dim if needed for Delaunay input site
0026 class QhullPoints {
0027 
0028 private:
0029 #//!\name Fields
0030     coordT *            point_first; //!< First coordinate of an array of points of point_dimension
0031     coordT *            point_end;   //!< End of point coordinates (end>=first).  Trailing coordinates ignored
0032     QhullQh *           qh_qh;       //!< Maybe initialized NULL to allow ownership by RboxPoints
0033                                      //!< qh_qh used for QhullPoint() and qh_qh->hull_dim in constructor
0034     int                 point_dimension;  //!< Dimension, >=0
0035 
0036 public:
0037 #//!\name Subtypes
0038     class const_iterator;
0039     class iterator;
0040     typedef QhullPoints::const_iterator ConstIterator;
0041     typedef QhullPoints::iterator       Iterator;
0042 
0043 #//!\name Construct
0044     //! QhullPoint, PointCoordinates, and QhullPoints have similar constructors
0045     //! If Qhull/QhullQh is not initialized, then QhullPoints.dimension() is zero unless explicitly set
0046     //! Cannot define QhullPoints(int pointDimension) since it is ambiguous with QhullPoints(QhullQh *qqh)
0047                         QhullPoints() : point_first(0), point_end(0), qh_qh(0), point_dimension(0) { }
0048                         QhullPoints(int pointDimension, countT coordinateCount2, coordT *c) : point_first(c), point_end(c+coordinateCount2), qh_qh(0), point_dimension(pointDimension) { QHULL_ASSERT(pointDimension>=0); }
0049     explicit            QhullPoints(const Qhull &q);
0050                         QhullPoints(const Qhull &q, countT coordinateCount2, coordT *c);
0051                         QhullPoints(const Qhull &q, int pointDimension, countT coordinateCount2, coordT *c);
0052     explicit            QhullPoints(QhullQh *qqh) : point_first(0), point_end(0), qh_qh(qqh), point_dimension(qqh ? qqh->hull_dim : 0) { }
0053                         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); }
0054                         QhullPoints(QhullQh *qqh, int pointDimension, countT coordinateCount2, coordT *c);
0055                         //! Copy constructor copies pointers but not contents.  Needed for return by value and parameter passing.
0056                         QhullPoints(const QhullPoints &other)  : point_first(other.point_first), point_end(other.point_end), qh_qh(other.qh_qh), point_dimension(other.point_dimension) {}
0057     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; }
0058                         ~QhullPoints() {}
0059 
0060 public:
0061 
0062 #//!\name Conversion
0063 
0064 #ifndef QHULL_NO_STL
0065     std::vector<QhullPoint> toStdVector() const;
0066 #endif //QHULL_NO_STL
0067 #ifdef QHULL_USES_QT
0068     QList<QhullPoint>   toQList() const;
0069 #endif //QHULL_USES_QT
0070 
0071 #//!\name GetSet
0072     // Constructs QhullPoint.  Cannot return reference.
0073     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); }
0074     // Constructs QhullPoint.  Cannot return reference.
0075     const QhullPoint    back() const { return last(); }
0076     QhullPoint          back() { return last(); }
0077     ConstIterator       begin() const { return ConstIterator(*this); }
0078     Iterator            begin() { return Iterator(*this); }
0079     ConstIterator       constBegin() const { return ConstIterator(*this); }
0080     const coordT *      constData() const { return point_first; }
0081     ConstIterator       constEnd() const { return ConstIterator(qh_qh, point_dimension, point_end); }
0082     coordT *            coordinates() const { return point_first; }
0083     countT              coordinateCount() const { return static_cast<countT>(point_end-point_first); } // WARN64
0084     countT              count() const { return static_cast<countT>(size()); } // WARN64
0085     const coordT *      data() const { return point_first; }
0086     coordT *            data() { return point_first; }
0087     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; }
0088     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; }
0089     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; }
0090     int                 dimension() const { return point_dimension; }
0091     ConstIterator       end() const { return ConstIterator(qh_qh, point_dimension, point_end); }
0092     Iterator            end() { return Iterator(qh_qh, point_dimension, point_end); }
0093     coordT *            extraCoordinates() const { return (extraCoordinatesCount() ? (point_end-extraCoordinatesCount()) : 0); }
0094     countT              extraCoordinatesCount() const;  // WARN64
0095     // Constructs QhullPoint.  Cannot return reference.
0096     const QhullPoint    first() const { return QhullPoint(qh_qh, point_dimension, point_first); }
0097     QhullPoint          first() { return QhullPoint(qh_qh, point_dimension, point_first); }
0098     // Constructs QhullPoint.  Cannot return reference.
0099     const QhullPoint    front() const { return first(); }
0100     QhullPoint          front() { return first(); }
0101     bool                includesCoordinates(const coordT *c) const { return (c>=point_first && c<point_end); }
0102     bool                isEmpty() const { return (point_end==point_first || point_dimension==0); }
0103     // Constructs QhullPoint.  Cannot return reference.
0104     const QhullPoint    last() const { QHULL_ASSERT(point_first!=0); return QhullPoint(qh_qh, point_dimension, point_end - point_dimension); }
0105     QhullPoint          last() { QHULL_ASSERT(point_first!=0); return QhullPoint(qh_qh, point_dimension, point_end - point_dimension); }
0106     bool                operator==(const QhullPoints &other) const;
0107     bool                operator!=(const QhullPoints &other) const { return (! operator==(other)); }
0108     QhullPoint          operator[](countT idx) const { return at(idx); }
0109     QhullQh *           qh() const { return qh_qh; }
0110     void                resetQhullQh(QhullQh *qqh);
0111     void                setDimension(int d) { point_dimension= d; }
0112     size_t              size() const { return (point_dimension ? (point_end-point_first)/point_dimension : 0); }
0113     QhullPoint          value(countT idx) const;
0114     QhullPoint          value(countT idx, QhullPoint &defaultValue) const;
0115 
0116 #//!\name Methods
0117     bool                contains(const QhullPoint &t) const;
0118     countT              count(const QhullPoint &t) const;
0119     countT              indexOf(const coordT *pointCoordinates) const;
0120     countT              indexOf(const coordT *pointCoordinates, int noThrow) const;
0121     countT              indexOf(const QhullPoint &t) const;
0122     countT              lastIndexOf(const QhullPoint &t) const;
0123     //! Returns a subset of the points, not a copy
0124     QhullPoints         mid(countT idx, countT length= -1) const;
0125 
0126 #//!\name QhullPoints::iterator
0127     // Modeled on qlist.h w/o QT_STRICT_ITERATORS
0128     // before const_iterator for conversion with comparison operators
0129     // See: QhullSet.h
0130     class iterator : public QhullPoint {
0131 
0132     public:
0133         typedef std::random_access_iterator_tag  iterator_category;
0134         typedef QhullPoint      value_type;
0135         typedef value_type *    pointer;
0136         typedef value_type &    reference;
0137         typedef ptrdiff_t       difference_type;
0138 
0139         explicit        iterator(const QhullPoints &ps) : QhullPoint(ps.qh(), ps.dimension(), ps.coordinates()) {}
0140                         iterator(const int pointDimension, coordT *c): QhullPoint(pointDimension, c) {}
0141                         iterator(const Qhull &q, coordT *c): QhullPoint(q, c) {}
0142                         iterator(const Qhull &q, int pointDimension, coordT *c): QhullPoint(q, pointDimension, c) {}
0143                         iterator(QhullQh *qqh, coordT *c): QhullPoint(qqh, c) {}
0144                         iterator(QhullQh *qqh, int pointDimension, coordT *c): QhullPoint(qqh, pointDimension, c) {}
0145                         iterator(const iterator &other): QhullPoint(*other) {}
0146         iterator &      operator=(const iterator &other) { defineAs( const_cast<iterator &>(other)); return *this; }
0147 
0148         // Need 'const QhullPoint' to maintain const
0149         const QhullPoint & operator*() const { return *this; }
0150         QhullPoint &    operator*() { return *this; }
0151         const QhullPoint * operator->() const { return this; }
0152         QhullPoint *    operator->() { return this; }
0153         // value instead of reference since advancePoint() modifies self
0154         QhullPoint      operator[](countT idx) const { QhullPoint result= *this; result.advancePoint(idx); return result; }
0155         bool            operator==(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates==o.point_coordinates && point_dimension==o.point_dimension); }
0156         bool            operator!=(const iterator &o) const { return (! operator==(o)); }
0157         bool            operator<(const iterator &o) const  { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates < o.point_coordinates; }
0158         bool            operator<=(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates <= o.point_coordinates; }
0159         bool            operator>(const iterator &o) const  { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates > o.point_coordinates; }
0160         bool            operator>=(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates >= o.point_coordinates; }
0161         // reinterpret_cast to break circular dependency
0162         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); }
0163         bool            operator!=(const QhullPoints::const_iterator &o) const { return (! operator==(reinterpret_cast<const iterator &>(o))); }
0164         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; }
0165         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; }
0166         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; }
0167         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; }
0168         iterator &      operator++() { advancePoint(1); return *this; }
0169         iterator        operator++(int) { iterator n= *this; operator++(); return iterator(n); }
0170         iterator &      operator--() { advancePoint(-1); return *this; }
0171         iterator        operator--(int) { iterator n= *this; operator--(); return iterator(n); }
0172         iterator &      operator+=(countT idx) { advancePoint(idx); return *this; }
0173         iterator &      operator-=(countT idx) { advancePoint(-idx); return *this; }
0174         iterator        operator+(countT idx) const { iterator n= *this; n.advancePoint(idx); return n; }
0175         iterator        operator-(countT idx) const { iterator n= *this; n.advancePoint(-idx); return n; }
0176         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); }
0177     };//QhullPoints::iterator
0178 
0179 #//!\name QhullPoints::const_iterator
0180     //!\todo QH11018 FIX: const_iterator same as iterator.  SHould have a common definition
0181     class const_iterator : public QhullPoint {
0182 
0183     public:
0184         typedef std::random_access_iterator_tag  iterator_category;
0185         typedef QhullPoint          value_type;
0186         typedef const value_type *  pointer;
0187         typedef const value_type &  reference;
0188         typedef ptrdiff_t           difference_type;
0189 
0190                         const_iterator(const QhullPoints::iterator &o) : QhullPoint(*o) {}
0191         explicit        const_iterator(const QhullPoints &ps) : QhullPoint(ps.qh(), ps.dimension(), ps.coordinates()) {}
0192                         const_iterator(const int pointDimension, coordT *c): QhullPoint(pointDimension, c) {}
0193                         const_iterator(const Qhull &q, coordT *c): QhullPoint(q, c) {}
0194                         const_iterator(const Qhull &q, int pointDimension, coordT *c): QhullPoint(q, pointDimension, c) {}
0195                         const_iterator(QhullQh *qqh, coordT *c): QhullPoint(qqh, c) {}
0196                         const_iterator(QhullQh *qqh, int pointDimension, coordT *c): QhullPoint(qqh, pointDimension, c) {}
0197                         const_iterator(const const_iterator &o) : QhullPoint(*o) {}
0198         const_iterator &operator=(const const_iterator &o) { defineAs(const_cast<const_iterator &>(o)); return *this; }
0199 
0200         // value/non-const since advancePoint(1), etc. modifies self
0201         const QhullPoint & operator*() const { return *this; }
0202         const QhullPoint * operator->() const { return this; }
0203         // value instead of reference since advancePoint() modifies self
0204         const QhullPoint operator[](countT idx) const { QhullPoint n= *this; n.advancePoint(idx); return n; }
0205         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); }
0206         bool            operator!=(const const_iterator &o) const { return (! operator==(o)); }
0207         bool            operator<(const const_iterator &o) const  { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates < o.point_coordinates); }
0208         bool            operator<=(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates <= o.point_coordinates); }
0209         bool            operator>(const const_iterator &o) const  { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates > o.point_coordinates); }
0210         bool            operator>=(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates >= o.point_coordinates); }
0211         const_iterator &operator++() { advancePoint(1); return *this; }
0212         const_iterator  operator++(int) { const_iterator n= *this; operator++(); return const_iterator(n); }
0213         const_iterator &operator--() { advancePoint(-1); return *this; }
0214         const_iterator  operator--(int) { const_iterator n= *this; operator--(); return const_iterator(n); }
0215         const_iterator &operator+=(countT idx) { advancePoint(idx); return *this; }
0216         const_iterator &operator-=(countT idx) { advancePoint(-idx); return *this; }
0217         const_iterator  operator+(countT idx) const { const_iterator n= *this; n.advancePoint(idx); return n; }
0218         const_iterator  operator-(countT idx) const { const_iterator n= *this; n.advancePoint(-idx); return n; }
0219         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); }
0220     };//QhullPoints::const_iterator
0221 
0222 #//!\name IO
0223     struct PrintPoints{
0224         const QhullPoints  *points;
0225         const char *    point_message;
0226         bool            with_identifier;
0227         PrintPoints(const char *message, bool withIdentifier, const QhullPoints &ps) : points(&ps), point_message(message), with_identifier(withIdentifier) {}
0228     };//PrintPoints
0229     PrintPoints          print(const char *message) const { return PrintPoints(message, false, *this); }
0230     PrintPoints          printWithIdentifier(const char *message) const { return PrintPoints(message, true, *this); }
0231 };//QhullPoints
0232 
0233 
0234 //! QhullPointsIterator is a Java-style iterator.  It may be used on temporary results.  It copies the pointers in QhullPoints
0235 //! Did not use QHULL_DECLARE_SEQUENTIAL_ITERATOR because next(),etc cannot return a reference to a temporary
0236 class QhullPointsIterator
0237 {
0238     typedef QhullPoints::const_iterator const_iterator;
0239 
0240 #//!\name Fields
0241 private:
0242     QhullPoints         ps;
0243     const_iterator      i;
0244 
0245 public:
0246                         QhullPointsIterator(const QhullPoints &other) : ps(other), i(ps.constBegin()) {}
0247     QhullPointsIterator &operator=(const QhullPoints &other) { ps= other; i= ps.constBegin(); return *this; }
0248 
0249     bool                findNext(const QhullPoint &t);
0250     bool                findPrevious(const QhullPoint &t);
0251     bool                hasNext() const { return i != ps.constEnd(); }
0252     bool                hasPrevious() const { return i != ps.constBegin(); }
0253     QhullPoint          next() { return *i++; }
0254     QhullPoint          peekNext() const { return *i; }
0255     QhullPoint          peekPrevious() const { const_iterator p= i; return *--p; }
0256     QhullPoint          previous() { return *--i; }
0257     void                toBack() { i= ps.constEnd(); }
0258     void                toFront() { i= ps.constBegin(); }
0259 };//QhullPointsIterator
0260 
0261 }//namespace orgQhull
0262 
0263 #//!\name Global
0264 
0265 std::ostream &          operator<<(std::ostream &os, const orgQhull::QhullPoints &p);
0266 std::ostream &          operator<<(std::ostream &os, const orgQhull::QhullPoints::PrintPoints &pr);
0267 
0268 #endif // QHULLPOINTS_H