You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
228 lines
6.7 KiB
C++
228 lines
6.7 KiB
C++
#pragma once
|
|
|
|
#include <iBase_global.h>
|
|
|
|
#define zxIsEqual(x, y, eps) ((x - y) < (eps) && (x - y) > (-eps))
|
|
|
|
template <class T>
|
|
class ZxInterval
|
|
{
|
|
public:
|
|
|
|
inline ZxInterval();
|
|
inline ZxInterval(const T &start, const T &stop);
|
|
inline virtual ~ZxInterval();
|
|
|
|
inline ZxInterval<T> &operator=(const ZxInterval<T>&);
|
|
inline virtual ZxInterval<T>* clone() const;
|
|
|
|
inline bool isUdf() const;
|
|
inline void set(const T &start, const T &stop);
|
|
inline bool isEqual(const ZxInterval<T> &i, const T &eps) const;
|
|
|
|
inline bool operator==(const ZxInterval<T>&) const;
|
|
inline bool operator!=(const ZxInterval<T>&) const;
|
|
inline ZxInterval<T> operator+(const ZxInterval<T>&) const;
|
|
inline ZxInterval<T> &operator+=(const ZxInterval<T>&);
|
|
|
|
template <class X> inline const ZxInterval<T> &setFrom(const ZxInterval<X>&);
|
|
|
|
inline T width(bool allowrev = true) const;
|
|
inline virtual T center() const;
|
|
inline void shift(const T &len);
|
|
inline void widen(const T &len, bool allowrev = true);
|
|
inline virtual void scale(const T&);
|
|
|
|
inline T atIndex(int, const T &step) const;
|
|
template <class X> inline int getIndex(const X&, const T &step) const;
|
|
template <class X> inline float getfIndex(const X&, const T &step) const;
|
|
template <class X> inline int nearestIndex(const X &x, const T &step) const;
|
|
|
|
template <class X> inline void limitTo(const ZxInterval<X> &i)
|
|
{ start = i.limitValue(start); stop = i.limitValue(stop); }
|
|
|
|
template <class X> inline X limitValue(const X&) const;
|
|
|
|
template <class X> inline bool overlaps(const ZxInterval<X>&, bool allrev = true) const;
|
|
template <class X> inline bool includes(const X&, bool allowrev = true) const;
|
|
template <class X> inline float pos(X val, bool limit = true, bool allowrev = true) const;
|
|
/*!< returns a value between 0 and 1 if val is
|
|
between start and stop. */
|
|
inline void include(const T&, bool allowrev = true);
|
|
inline void include(const ZxInterval<T>&, bool allowrev = true);
|
|
|
|
inline virtual void sort(bool asc = true);
|
|
|
|
T start;
|
|
T stop;
|
|
|
|
inline bool isRev() const;
|
|
inline virtual bool hasStep() const;
|
|
};
|
|
|
|
template <class T>
|
|
inline ZxInterval<T> &ZxInterval<T>::operator=(const ZxInterval<T> &intv)
|
|
{ start = intv.start; stop = intv.stop; return *this; }
|
|
|
|
template <class T> template <class X>
|
|
inline int ZxInterval<T>::nearestIndex(const X &x, const T &step) const
|
|
{
|
|
int nr = getIndex(x, step);
|
|
const T atindex = atIndex(nr, step);
|
|
const float reldiff = (float)(x-atindex)/step;
|
|
|
|
if (reldiff>=0.5) return nr+1;
|
|
else if (reldiff<=-0.5) return nr-1;
|
|
return nr;
|
|
}
|
|
|
|
template <class T> inline ZxInterval<T>::ZxInterval()
|
|
{ start = 0; stop = 0; }
|
|
|
|
template <class T> inline ZxInterval<T>::ZxInterval(const T &t1, const T &t2)
|
|
{ start = t1; stop = t2; }
|
|
|
|
template <class T> inline ZxInterval<T>::~ZxInterval() {}
|
|
|
|
template <class T>
|
|
inline bool ZxInterval<T>::isUdf() const
|
|
{ return zxIsUdf(start) || zxIsUdf(stop); }
|
|
|
|
template <class T>
|
|
inline ZxInterval<T>* ZxInterval<T>::clone() const
|
|
{ return new ZxInterval<T>(*this); }
|
|
|
|
template <class T>
|
|
inline void ZxInterval<T>::set(const T &t1, const T &t2)
|
|
{ start = t1; stop = t2; }
|
|
|
|
template <class T>
|
|
inline bool ZxInterval<T>::isEqual(const ZxInterval<T> &i, const T &eps) const
|
|
{ return zxIsEqual(start, i.start, eps) && zxIsEqual(stop, i.stop, eps); }
|
|
|
|
template <class T>
|
|
inline bool ZxInterval<T>::operator==(const ZxInterval<T> &i) const
|
|
{ return start == i.start && stop == i.stop; }
|
|
|
|
template <class T>
|
|
inline bool ZxInterval<T>::operator!=(const ZxInterval<T> &i) const
|
|
{ return ! (i == *this); }
|
|
|
|
template <class T>
|
|
inline ZxInterval<T> ZxInterval<T>::operator+(const ZxInterval<T> &i) const
|
|
{ return ZxInterval<T>(start+i.start, stop+i.stop); }
|
|
|
|
template <class T>
|
|
inline ZxInterval<T> &ZxInterval<T>::operator+=(const ZxInterval<T> &i)
|
|
{ start += i.start; stop += i.stop; return *this; }
|
|
|
|
template <class T> template <class X>
|
|
inline const ZxInterval<T> &ZxInterval<T>::setFrom(const ZxInterval<X> &i)
|
|
{
|
|
start = (T) i.start;
|
|
stop = (T) i.stop;
|
|
return *this;
|
|
}
|
|
|
|
template <class T>
|
|
inline T ZxInterval<T>::width(bool allowrev) const
|
|
{ return allowrev && isRev()? start - stop : stop - start; }
|
|
|
|
template <class T>
|
|
inline T ZxInterval<T>::center() const
|
|
{ return (start+stop)/2; }
|
|
|
|
template <class T>
|
|
inline void ZxInterval<T>::shift(const T &len)
|
|
{ start += len; stop += len; }
|
|
|
|
template <class T>
|
|
inline void ZxInterval<T>::widen(const T &len, bool allowrev)
|
|
{
|
|
if (allowrev && isRev())
|
|
{ start += len; stop -= len; }
|
|
else
|
|
{ start -= len; stop += len; }
|
|
}
|
|
|
|
template <class T>
|
|
inline void ZxInterval<T>::scale(const T &factor)
|
|
{ start *= factor; stop *= factor; }
|
|
|
|
template <class T> template <class X>
|
|
inline bool ZxInterval<T>::includes(const X &t, bool allowrev) const
|
|
{
|
|
return allowrev && isRev()
|
|
? t >= stop && start >= t
|
|
: t >= start && stop >= t;
|
|
}
|
|
|
|
template <class T> template <class X>
|
|
inline float ZxInterval<T>::pos(X val, bool limit, bool allowrev) const
|
|
{
|
|
float res = allowrev && isRev()
|
|
? (val-stop)/(start-stop)
|
|
: (val-start)/(stop-start);
|
|
if (limit)
|
|
{
|
|
if (res<0) res = 0;
|
|
else if (res>1) res = 1;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
template <class T> template <class X>
|
|
inline bool ZxInterval<T>::overlaps(const ZxInterval<X> &t, bool allowrev) const
|
|
{
|
|
return includes(t.start, allowrev) || includes(t.stop, allowrev) ||
|
|
t.includes(start, allowrev) || t.includes(stop, allowrev);
|
|
}
|
|
|
|
template <class T>
|
|
inline void ZxInterval<T>::include(const T &i, bool allowrev)
|
|
{
|
|
if (allowrev && isRev())
|
|
{ if (stop>i) stop=i; if (start<i) start=i; }
|
|
else
|
|
{ if (start>i) start=i; if (stop<i) stop=i; }
|
|
}
|
|
|
|
template <class T>
|
|
inline void ZxInterval<T>::include(const ZxInterval<T> &i, bool allowrev)
|
|
{ include(i.start, allowrev); include(i.stop, allowrev); }
|
|
|
|
template <class T>
|
|
inline T ZxInterval<T>::atIndex(int idx, const T &step) const
|
|
{ return start + step * idx; }
|
|
|
|
template <class T> template <class X>
|
|
inline int ZxInterval<T>::getIndex(const X &t, const T &step) const
|
|
{ return (int)((t - start) / step); }
|
|
|
|
template <class T> template <class X>
|
|
inline float ZxInterval<T>::getfIndex(const X &t, const T &step) const
|
|
{ return (((float)t - start) / step); }
|
|
|
|
template <class T> template <class X>
|
|
inline X ZxInterval<T>::limitValue(const X &t) const
|
|
{
|
|
const bool isrev = isRev();
|
|
if ((!isrev&&t>stop) || (isrev&&t<stop)) return stop;
|
|
if ((!isrev&&t<start) || (isrev&&t>start)) return start;
|
|
return t;
|
|
}
|
|
|
|
template <class T>
|
|
inline void ZxInterval<T>::sort(bool asc)
|
|
{
|
|
if ((asc && stop<start) || (!asc && start<stop))
|
|
qSwap(start, stop);
|
|
}
|
|
|
|
template <class T> inline bool ZxInterval<T>::hasStep() const
|
|
{ return false; }
|
|
|
|
|
|
|
|
|