| #pragma once |
| |
| #ifndef T_INTERVAL_INCLUDED |
| #define T_INTERVAL_INCLUDED |
| |
| #include <assert.h> |
| #include <limits.h> |
| #include "tcommon.h" |
| |
| #undef DVAPI |
| #undef DVVAR |
| #ifdef TNZCORE_EXPORTS |
| #define DVAPI DV_EXPORT_API |
| #define DVVAR DV_EXPORT_VAR |
| #else |
| #define DVAPI DV_IMPORT_API |
| #define DVVAR DV_IMPORT_VAR |
| #endif |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| class TInterval { |
| double m_min, m_max; |
| |
| public: |
| |
| |
| TInterval() : m_min(1), m_max(-1) {} |
| |
| |
| TInterval(double x) : m_min(x), m_max(x) {} |
| |
| TInterval(double min, double max) { |
| assert(min <= max); |
| m_min = min; |
| m_max = max; |
| } |
| |
| TInterval(const TInterval &w) { |
| assert(w.m_min <= w.m_max || |
| (w.m_min == 1 && w.m_max == -1)); |
| m_min = w.m_min; |
| m_max = w.m_max; |
| } |
| |
| inline TInterval &operator=(const TInterval &w) { |
| assert(w.m_min <= w.m_max || |
| (w.m_min == 1 && w.m_max == -1)); |
| m_min = w.m_min; |
| m_max = w.m_max; |
| return *this; |
| } |
| |
| inline TInterval operator+() const { |
| assert(m_min <= m_max); |
| return *this; |
| } |
| |
| inline TInterval operator-() const { |
| assert(m_min <= m_max); |
| return TInterval(-m_max, -m_min); |
| } |
| |
| inline TInterval operator+(const TInterval &w) const { |
| assert(m_min <= m_max); |
| assert(w.m_min <= w.m_max); |
| return TInterval(m_min + w.m_min, m_max + w.m_max); |
| } |
| |
| inline TInterval operator-(const TInterval &w) const { |
| assert(m_min <= m_max); |
| assert(w.m_min <= w.m_max); |
| return TInterval(m_min - w.m_max, m_max - w.m_min); |
| } |
| |
| inline TInterval operator*(const TInterval &w) const { |
| assert(m_min <= m_max); |
| assert(w.m_min <= w.m_max); |
| double value[4]; |
| value[0] = m_min * w.m_min; |
| value[1] = m_min * w.m_max; |
| value[2] = m_max * w.m_min; |
| value[3] = m_max * w.m_max; |
| double minValue = value[0]; |
| double maxValue = value[0]; |
| int i = 1; |
| for (i = 1; i <= 3; ++i) { |
| if (value[i] < minValue) minValue = value[i]; |
| if (value[i] > maxValue) maxValue = value[i]; |
| } |
| return TInterval(minValue, maxValue); |
| } |
| |
| inline TInterval operator/(const TInterval &w) const { |
| assert(m_min <= m_max); |
| assert(w.m_min <= w.m_max); |
| assert((0 < w.m_min && 0 < w.m_max) || |
| (0 > w.m_min && 0 > w.m_max)); |
| double value[4]; |
| value[0] = m_min / w.m_min; |
| value[1] = m_min / w.m_max; |
| value[2] = m_max / w.m_min; |
| value[3] = m_max / w.m_max; |
| double minValue = value[0]; |
| double maxValue = value[0]; |
| int i = 1; |
| for (i = 1; i <= 3; ++i) { |
| if (value[i] < minValue) minValue = value[i]; |
| if (value[i] > maxValue) maxValue = value[i]; |
| } |
| return TInterval(minValue, maxValue); |
| } |
| |
| inline bool operator==(const TInterval &w) const { |
| assert(w.m_min <= w.m_max || |
| (w.m_min == 1 && w.m_max == -1)); |
| return (m_min == w.m_min && m_max == w.m_max); |
| } |
| |
| |
| |
| |
| |
| |
| inline bool operator>(const TInterval &w) const { |
| assert(m_min <= m_max); |
| assert(w.m_min <= w.m_max); |
| return (m_min > w.m_max); |
| } |
| |
| inline bool operator<(const TInterval &w) const { |
| assert(m_min <= m_max); |
| assert(w.m_min <= w.m_max); |
| return (m_max < w.m_min); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| inline void setMin(double min) { |
| assert(m_min <= m_max); |
| assert(min <= m_max); |
| m_min = min; |
| } |
| |
| inline void setMax(double max) { |
| assert(m_min <= m_max); |
| assert(m_min <= max); |
| m_max = max; |
| } |
| |
| inline double getMin() const { |
| |
| return m_min; |
| } |
| |
| inline double getMax() const { |
| |
| return m_max; |
| } |
| |
| inline double getLength() const { |
| return m_max - m_min; |
| } |
| |
| inline double getCenter() const { |
| assert(m_min <= m_max); |
| return (m_max + m_min) / 2; |
| } |
| |
| inline double getRadius() const { |
| assert(m_min <= m_max); |
| return (m_max - m_min) / 2; |
| } |
| |
| inline bool isEmpty() const { |
| |
| assert(m_min <= m_max || (m_min == 1 && m_max == -1)); |
| return (m_min > m_max); |
| } |
| |
| |
| inline bool isProper() const { |
| |
| |
| assert(m_min <= m_max || (m_min == 1 && m_max == -1)); |
| return (m_min < m_max); |
| } |
| |
| inline bool contain(double t) const { |
| assert(m_min <= m_max || (m_min == 1 && m_max == -1)); |
| return (m_min <= t && t <= m_max); |
| } |
| |
| inline bool include(const TInterval &interval) const { |
| if (interval.isEmpty()) |
| return true; |
| else if (isEmpty()) |
| return false; |
| else { |
| assert(!interval.isEmpty() && !isEmpty()); |
| return (m_min <= interval.m_min && interval.m_max <= m_max); |
| } |
| } |
| |
| inline bool isIncluded(const TInterval &interval) const { |
| if (isEmpty()) |
| return true; |
| else if (interval.isEmpty()) |
| return false; |
| else { |
| assert(!isEmpty() && !interval.isEmpty()); |
| return (interval.m_min <= m_min && m_max <= interval.m_max); |
| } |
| } |
| |
| |
| friend TInterval operator*(const double s, const TInterval &w); |
| friend TInterval intersection(const TInterval &a, const TInterval &b); |
| friend TInterval square(const TInterval &w); |
| friend TInterval sqrt(const TInterval &w); |
| }; |
| |
| |
| inline TInterval operator*(const double s, const TInterval &w) { |
| assert(w.m_min <= w.m_max); |
| if (s >= 0) |
| return TInterval(s * w.m_min, s * w.m_max); |
| else |
| return TInterval(s * w.m_max, s * w.m_min); |
| } |
| |
| inline TInterval square(const TInterval &w) { |
| |
| assert(w.m_min <= w.m_max); |
| double a = w.m_min * w.m_min; |
| double b = w.m_max * w.m_max; |
| if (0 <= w.m_min) |
| return TInterval(a, b); |
| else if (w.m_max <= 0) |
| return TInterval(b, a); |
| else { |
| assert(w.m_min < 0 && 0 < w.m_max); |
| return TInterval(0, std::max(a, b)); |
| } |
| } |
| |
| inline TInterval sqrt(const TInterval &w) { |
| |
| assert(w.m_min <= w.m_max); |
| assert(0 <= w.m_min); |
| return TInterval(sqrt(w.m_min), sqrt(w.m_max)); |
| } |
| |
| |
| inline TInterval intersection(const TInterval &a, const TInterval &b) { |
| |
| |
| double min = std::max(a.m_min, b.m_min); |
| double max = std::min(a.m_max, b.m_max); |
| if (min <= max) |
| |
| return TInterval(min, max); |
| else |
| return TInterval(); |
| } |
| |
| inline TInterval createTInterval(double center, double radius) { |
| if (radius >= 0) |
| return TInterval(center - radius, center + radius); |
| else |
| return TInterval(); |
| } |
| |
| inline TInterval createErrorTInterval( |
| double center, double minError = (std::numeric_limits<double>::min)()) { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| assert(minError >= 0); |
| const double relativeDoubleError = 1e-13; |
| double error = std::max(fabs(center) * relativeDoubleError, minError); |
| return TInterval(center - error, center + error); |
| } |
| |
| |
| #endif // __T_INTERVAL_INCLUDED__ |