00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef __UT_Interval_h__
00015 #define __UT_Interval_h__
00016
00017 #include "UT_API.h"
00018 #include "UT_Math.h"
00019
00020 #ifdef WIN32
00021 #undef min
00022 #undef max
00023 #endif
00024
00025 class UT_API UT_Interval {
00026 public:
00027 explicit UT_Interval(fpreal a = 0);
00028 UT_Interval(fpreal a, fpreal b, bool order=false);
00029 UT_Interval &operator+=(const UT_Interval &rhs);
00030 UT_Interval &operator-=(const UT_Interval &rhs);
00031 UT_Interval &operator*=(const UT_Interval &rhs);
00032 UT_Interval &operator/=(const UT_Interval &rhs);
00033 UT_Interval &operator|=(const UT_Interval &rhs);
00034 UT_Interval &operator&=(const UT_Interval &rhs);
00035 UT_Interval &operator+=(fpreal rhs);
00036 UT_Interval &operator-=(fpreal rhs);
00037 UT_Interval &operator*=(fpreal rhs);
00038 bool operator==(const UT_Interval &rhs) const;
00039 bool operator!=(const UT_Interval &rhs) const;
00040 void assign(fpreal Min, fpreal Max, bool order_them=false)
00041 {
00042 min = Min;
00043 max = Max;
00044 if (order_them && min > max)
00045 {
00046 fpreal tmp = min;
00047 min = max;
00048 max = tmp;
00049 }
00050 }
00051 void extendToContain( fpreal a );
00052 void minWith(const UT_Interval &rhs);
00053 void maxWith(const UT_Interval &rhs);
00054 void order();
00055 fpreal closest(fpreal val) const;
00056 fpreal closest(fpreal val, fpreal wrap) const;
00057 fpreal avg() const { return (max+min)*0.5; }
00058 fpreal delta() const { return max - min; }
00059 void square();
00060 UT_Interval sqr() const;
00061 UT_Interval abs() const;
00062 UT_Interval pow(float arg) const;
00063 int contains(fpreal arg) const;
00064 int isValid(fpreal tol = 0.f) const;
00065 void display() const;
00066 int equalZero(fpreal tol = 0.00001f) const
00067 {
00068 return ((min>=-tol) && (min <= tol) && (max >=-tol) && (max <= tol));
00069 }
00070
00071 int isEqual(const UT_Interval &v, fpreal tol = 0.00001f) const
00072 {
00073 return ((min>=v.min-tol) && (min<=v.min+tol) &&
00074 (max>=v.max-tol) && (max<=v.max+tol));
00075 }
00076
00077 void clampZero(fpreal tol = 0.00001f)
00078 {
00079 if (min>=-tol && min<= tol) min = 0;
00080 if (max>=-tol && max<= tol) max = 0;
00081 }
00082
00083 void negate()
00084 {
00085 fpreal tmp = min;
00086 min = -max;
00087 max = -tmp;
00088 }
00089 void invert(UT_Interval &v) const
00090 {
00091 v.min = min;
00092 v.max = max;
00093 if (!v.min)
00094 v.min+=0.00001f;
00095 if(!v.max)
00096 v.max+=0.00001f;
00097 fpreal tmp = v.min;
00098 v.min = 1/v.max;
00099 v.max = 1/tmp;
00100
00101 }
00102 void invert()
00103 {
00104 if (!min)
00105 min+=0.00001f;
00106 if(!max)
00107 max+=0.00001f;
00108 fpreal tmp = min;
00109 min = 1/max;
00110 max = 1/tmp;
00111 }
00112 public:
00113 float min, max;
00114 };
00115
00116 inline UT_Interval operator+(const UT_Interval &lhs, const UT_Interval &rhs);
00117 inline UT_Interval operator+(fpreal lhs, const UT_Interval &rhs);
00118 inline UT_Interval operator+(const UT_Interval &lhs, fpreal rhs);
00119 inline UT_Interval operator-(const UT_Interval &lhs, const UT_Interval &rhs);
00120 inline UT_Interval operator-(fpreal lhs, const UT_Interval &rhs);
00121 inline UT_Interval operator-(const UT_Interval &lhs, fpreal rhs);
00122 inline UT_Interval operator-(const UT_Interval &rhs);
00123 inline UT_Interval operator*(const UT_Interval &lhs, const UT_Interval &rhs);
00124 inline UT_Interval operator*(fpreal lhs, const UT_Interval &rhs);
00125 inline UT_Interval operator*(const UT_Interval &lhs, fpreal rhs);
00126 inline UT_Interval operator/(const UT_Interval &lhs, const UT_Interval &rhs);
00127 inline UT_Interval operator/(fpreal lhs, const UT_Interval &rhs);
00128 inline UT_Interval operator/(const UT_Interval &lhs, fpreal rhs);
00129 inline UT_Interval operator|(const UT_Interval &lhs, const UT_Interval &rhs);
00130 inline UT_Interval operator&(const UT_Interval &lhs, const UT_Interval &rhs);
00131 inline UT_Interval maxOf(const UT_Interval &arg0, const UT_Interval &arg1);
00132 inline UT_Interval minOf(const UT_Interval &arg0, const UT_Interval &arg1);
00133
00134
00135
00136
00137
00138 inline UT_Interval::UT_Interval(fpreal a): min(a), max(a) {}
00139 inline UT_Interval::UT_Interval(fpreal a, fpreal b, bool order_them)
00140 : min(a),
00141 max(b)
00142 {
00143 if (order_them && min > max)
00144 {
00145 fpreal tmp = min;
00146 min = max;
00147 max = tmp;
00148 }
00149 }
00150
00151 inline UT_Interval &UT_Interval::operator+=(const UT_Interval &rhs)
00152 {
00153 min += rhs.min;
00154 max += rhs.max;
00155 return *this;
00156 }
00157
00158 inline UT_Interval &UT_Interval::operator+=(fpreal rhs)
00159 {
00160 min += rhs;
00161 max += rhs;
00162 return *this;
00163 }
00164
00165 inline UT_Interval &UT_Interval::operator-=(const UT_Interval &rhs)
00166 {
00167 fpreal t = rhs.min;
00168 min -= rhs.max;
00169 max -= t;
00170 return *this;
00171 }
00172
00173 inline UT_Interval &UT_Interval::operator-=(fpreal rhs)
00174 {
00175 min -= rhs;
00176 max -= rhs;
00177 return *this;
00178 }
00179
00180 inline UT_Interval &UT_Interval::operator*=(const UT_Interval &rhs)
00181 {
00182 fpreal t1 = min*rhs.min;
00183 fpreal t2 = max*rhs.min;
00184 fpreal t3 = min*rhs.max;
00185 fpreal t4 = max*rhs.max;
00186 fpreal tmin, tmax;
00187
00188 if (t1 < t2) { tmin = t1; tmax = t2; }
00189 else { tmin = t2; tmax = t1; }
00190 if (tmax < t3) { tmax = t3; }
00191 if (tmin > t3) { tmin = t3; }
00192 if (tmax < t4) { tmax = t4; }
00193 if (tmin > t4) { tmin = t4; }
00194 min = tmin;
00195 max = tmax;
00196 return *this;
00197 }
00198
00199 inline UT_Interval &UT_Interval::operator/=(const UT_Interval &rhs)
00200 {
00201 UT_Interval inverted;
00202 rhs.invert(inverted);
00203 (*this) *= inverted;
00204 return *this;
00205 }
00206
00207
00208
00209 inline UT_Interval &UT_Interval::operator*=(fpreal rhs)
00210 {
00211 if (rhs >= 0.0F) { min *= rhs; max *= rhs; }
00212 else { fpreal t = min * rhs; min = max * rhs; max = t; }
00213 return *this;
00214 }
00215 inline bool UT_Interval::operator==(const UT_Interval &rhs) const
00216 {
00217 return min == rhs.min && max == rhs.max;
00218 }
00219 inline bool UT_Interval::operator!=(const UT_Interval &rhs) const
00220 {
00221 return min != rhs.min || max != rhs.max;
00222 }
00223
00224
00225 inline void UT_Interval::maxWith(const UT_Interval &rhs)
00226 {
00227 if (min < rhs.min) min = rhs.min;
00228 if (max < rhs.max) max = rhs.max;
00229 }
00230
00231 inline void UT_Interval::extendToContain( fpreal a )
00232 {
00233 if( min>a )
00234 min = a;
00235 else if( max<a )
00236 max = a;
00237 }
00238
00239 inline void UT_Interval::minWith(const UT_Interval &rhs)
00240 {
00241 if (min > rhs.min) min = rhs.min;
00242 if (max > rhs.max) max = rhs.max;
00243 }
00244
00245 inline UT_Interval &UT_Interval::operator|=(const UT_Interval &rhs)
00246 {
00247 if (min > rhs.min) min = rhs.min;
00248 if (max < rhs.max) max = rhs.max;
00249 return *this;
00250 }
00251
00252 inline UT_Interval &UT_Interval::operator&=(const UT_Interval &rhs)
00253 {
00254 if (min < rhs.min) min = rhs.min;
00255 if (max > rhs.max) max = rhs.max;
00256 return *this;
00257 }
00258
00259
00260 inline UT_Interval UT_Interval::sqr() const
00261 {
00262 fpreal tmin, tmax;
00263 if (min < 0.0F) {
00264 if (max < 0.0F) {
00265 tmin = max*max;
00266 tmax = min*min;
00267 }
00268 else {
00269 tmin = min*min;
00270 tmax = max*max;
00271 tmax = (tmin < tmax) ? tmax : tmin;
00272 tmin = 0.0F;
00273 }
00274 }
00275 else {
00276 tmin = min*min;
00277 tmax = max*max;
00278 }
00279 return UT_Interval(tmin, tmax);
00280 }
00281
00282 inline void UT_Interval::square()
00283 {
00284 fpreal tmin, tmax;
00285 if (min < 0.0F) {
00286 if (max < 0.0F) {
00287 tmin = max*max;
00288 tmax = min*min;
00289 }
00290 else {
00291 tmin = min*min;
00292 tmax = max*max;
00293 tmax = (tmin < tmax) ? tmax : tmin;
00294 tmin = 0.0F;
00295 }
00296 }
00297 else {
00298 tmin = min*min;
00299 tmax = max*max;
00300 }
00301 min = tmin;
00302 max = tmax;
00303 }
00304
00305
00306 inline UT_Interval UT_Interval::abs() const
00307 {
00308 if (max < 0.0F) {
00309 return UT_Interval(-max, -min);
00310 }
00311 else if (min < 0.0F) {
00312 fpreal tmax;
00313 if (-min > max) tmax = -min;
00314 else tmax = max;
00315 return UT_Interval(0.0F, tmax);
00316 }
00317 return *this;
00318 }
00319
00320 inline fpreal
00321 UT_Interval::closest(fpreal val) const
00322 {
00323 fpreal dmin, dmax;
00324
00325 dmin = val - min;
00326 dmax = max - val;
00327 if (dmin < 0.0F)
00328 return min;
00329 else if (dmax < 0.0F)
00330 return max;
00331 return val;
00332 }
00333
00334 inline fpreal
00335 UT_Interval::closest(fpreal val, fpreal wrap) const
00336 {
00337 fpreal dmin, dmax;
00338
00339 dmin = val - min;
00340 dmax = max - val;
00341 if (dmin < 0.0F)
00342 {
00343 if (dmin < dmax - wrap)
00344 return max;
00345 else
00346 return min;
00347 }
00348 else if (dmax < 0.0F)
00349 {
00350 if (dmin - wrap < dmax)
00351 return max;
00352 else
00353 return min;
00354 }
00355 return val;
00356 }
00357
00358 #if 0
00359
00360
00361 inline UT_Interval UT_Interval::pow(fpreal arg) const
00362 {
00363 if (arg > 0) return UT_Interval(powf(min, arg), powf(max, arg));
00364 else return UT_Interval(powf(max, arg), powf(min, arg));
00365 }
00366 #endif
00367
00368 inline int UT_Interval::contains(fpreal arg) const
00369 {
00370 return ((arg >= min) && (arg <= max));
00371 }
00372
00373 inline int UT_Interval::isValid(fpreal tol) const
00374 {
00375 return UTisLessOrEqual(min, max, tol);
00376 }
00377
00378 inline void UT_Interval::order()
00379 {
00380 if (min > max)
00381 {
00382 fpreal tmp = min;
00383 min = max;
00384 max = tmp;
00385 }
00386 }
00387
00388
00389
00390 inline UT_Interval operator+(const UT_Interval &lhs, const UT_Interval &rhs)
00391 {
00392 return UT_Interval(lhs.min + rhs.min, lhs.max + rhs.max);
00393 }
00394
00395 inline UT_Interval operator+(fpreal lhs, const UT_Interval &rhs)
00396 {
00397 return UT_Interval(rhs.min + lhs, rhs.max + lhs);
00398 }
00399
00400
00401 inline UT_Interval operator+(const UT_Interval &lhs, fpreal rhs)
00402 {
00403 return UT_Interval(lhs.min + rhs, lhs.max + rhs);
00404 }
00405
00406 inline UT_Interval operator-(const UT_Interval &lhs, const UT_Interval &rhs)
00407 {
00408 return UT_Interval(lhs.min - rhs.max, lhs.max - rhs.min);
00409 }
00410
00411 inline UT_Interval operator-(fpreal lhs, const UT_Interval &rhs)
00412 {
00413 return UT_Interval(lhs - rhs.max, lhs - rhs.min);
00414 }
00415
00416 inline UT_Interval operator-(const UT_Interval &lhs, fpreal rhs)
00417 {
00418 return UT_Interval(lhs.min - rhs, lhs.max - rhs);
00419 }
00420
00421 inline UT_Interval operator-(const UT_Interval &rhs)
00422 {
00423 return UT_Interval(-rhs.max, -rhs.min);
00424 }
00425
00426 inline UT_Interval operator*(const UT_Interval &lhs, const UT_Interval &rhs)
00427 {
00428 fpreal t1 = lhs.min*rhs.min;
00429 fpreal t2 = lhs.max*rhs.min;
00430 fpreal t3 = lhs.min*rhs.max;
00431 fpreal t4 = lhs.max*rhs.max;
00432 fpreal tmin, tmax;
00433
00434 if (t1 < t2) { tmin = t1; tmax = t2; }
00435 else { tmin = t2; tmax = t1; }
00436 if (tmax < t3) { tmax = t3; }
00437 if (tmin > t3) { tmin = t3; }
00438 if (tmax < t4) { tmax = t4; }
00439 if (tmin > t4) { tmin = t4; }
00440 return UT_Interval(tmin, tmax);
00441 }
00442
00443 inline UT_Interval operator*(fpreal lhs, const UT_Interval &rhs)
00444 {
00445 fpreal tmin, tmax;
00446 if (lhs > 0.0F) { tmin = lhs*rhs.min; tmax = lhs*rhs.max; }
00447 else { tmin = lhs*rhs.max; tmax = lhs*rhs.min; }
00448 return UT_Interval(tmin, tmax);
00449 }
00450
00451 inline UT_Interval operator*(const UT_Interval &lhs, fpreal rhs)
00452 {
00453 fpreal tmin, tmax;
00454 if (rhs > 0.0F) { tmin = rhs*lhs.min; tmax = rhs*lhs.max; }
00455 else { tmin = rhs*lhs.max; tmax = rhs*lhs.min; }
00456 return UT_Interval(tmin, tmax);
00457 }
00458
00459 inline UT_Interval operator|(const UT_Interval &lhs, const UT_Interval &rhs)
00460 {
00461 return UT_Interval((lhs.min < rhs.min)? lhs.min : rhs.min,
00462 (lhs.max < rhs.max)? rhs.max : lhs.max);
00463 }
00464
00465 inline UT_Interval operator&(const UT_Interval &lhs, const UT_Interval &rhs)
00466 {
00467 return UT_Interval((lhs.min < rhs.min)? rhs.min : lhs.min,
00468 (lhs.max < rhs.max)? lhs.max : rhs.max);
00469 }
00470 inline UT_Interval operator/(const UT_Interval &lhs, const UT_Interval &rhs)
00471 {
00472 UT_Interval v;
00473 rhs.invert(v);
00474 return lhs * v;
00475 }
00476
00477 inline UT_Interval operator/(fpreal lhs, const UT_Interval &rhs)
00478 {
00479 UT_Interval v;
00480 rhs.invert(v);
00481 v *= lhs;
00482 return v;
00483 }
00484
00485 inline UT_Interval operator/(const UT_Interval &lhs, fpreal rhs)
00486 {
00487 if (!rhs) rhs += 0.00001f;
00488 return UT_Interval(lhs.min / rhs, lhs.max / rhs);
00489 }
00490
00491
00492 inline UT_Interval maxOf(const UT_Interval &arg0, const UT_Interval &arg1)
00493 {
00494 return UT_Interval((arg0.min < arg1.min)? arg1.min : arg0.min,
00495 (arg0.max < arg1.max)? arg1.max : arg0.max);
00496 }
00497
00498 inline UT_Interval minOf(const UT_Interval &arg0, const UT_Interval &arg1)
00499 {
00500 return UT_Interval((arg0.min < arg1.min)? arg0.min : arg1.min,
00501 (arg0.max < arg1.max)? arg0.max : arg1.max);
00502 }
00503
00504 #endif // __UT_Interval_h__