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.
nmWATI/Include/iBase/iProperty/PtyItems/ZxInterval.h

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; }