Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_MATH_INTERVAL_H
00002 #define OPENTISSUE_CORE_MATH_INTERVAL_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/math/interval/io/interval_io.h>
00013 #include <OpenTissue/core/math/interval/interval_vector.h>
00014 #include <OpenTissue/core/math/interval/interval_matrix.h>
00015 #include <OpenTissue/core/math/interval/interval_intersect.h>
00016 #include <OpenTissue/core/math/interval/interval_empty.h>
00017
00018 #include <OpenTissue/core/math/math_value_traits.h>
00019
00020
00021 #include <cassert>
00022
00023 namespace OpenTissue
00024 {
00025 namespace math
00026 {
00027 namespace interval
00028 {
00029
00057 template <typename value_type_>
00058 class Interval
00059 {
00060 public:
00061
00062 typedef value_type_ T;
00063 typedef typename math::ValueTraits<T> value_traits;
00064 typedef T value_type;
00065 typedef T base_type;
00066 typedef size_t index_type;
00067
00068 protected:
00069
00070 T m_lower;
00071 T m_upper;
00072
00073 public:
00074
00075 T & lower() { return m_lower; }
00076 T const & lower() const { return m_lower; }
00077 T & upper() { return m_upper; }
00078 T const & upper() const { return m_upper; }
00079
00088 T & operator() (index_type index)
00089 {
00090 assert(index==0u || index==1u || !"interval::operator(): index must be zero or one");
00091 return (!index) ? m_lower : m_upper;
00092 }
00093
00102 T const & operator() (index_type index) const
00103 {
00104 assert(index==0u || index==1u || !"interval::operator() const : index must be zero or one");
00105 return (!index) ? m_lower : m_upper;
00106 }
00107
00116 T & operator[] (index_type index)
00117 {
00118 assert(index==0u || index==1u || !"interval::operator[]: index must be zero or one");
00119 return (!index) ? m_lower : m_upper;
00120 }
00121
00130 T const & operator[] (index_type index) const
00131 {
00132 assert(index==0u || index==1u || !"interval::operator[] const : index must be zero or one");
00133 return (!index) ? m_lower : m_upper;
00134 }
00135
00136 public:
00137
00138 Interval()
00139 : m_lower()
00140 , m_upper()
00141 {}
00142
00143 Interval(Interval const &i)
00144 : m_lower( i.m_lower )
00145 , m_upper( i.m_upper )
00146 {}
00147
00148 explicit Interval(T const & value)
00149 : m_lower( value )
00150 , m_upper( value )
00151 {}
00152
00153 explicit Interval(T const & l, T const & u)
00154 : m_lower( l )
00155 , m_upper( u )
00156 {
00157
00158 }
00159
00160 ~Interval() {}
00161
00162 public:
00163
00174 Interval & operator=(Interval const &rhs)
00175 {
00176 m_lower = rhs.m_lower;
00177 m_upper = rhs.m_upper;
00178 return (*this);
00179 }
00180
00181
00182 void assign(T const &l, T const &u)
00183 {
00184 m_lower = l;
00185 m_upper = u;
00186 }
00187
00193 void clear()
00194 {
00195 m_lower = m_upper = value_traits::zero();
00196 }
00197
00203 bool is_valid() const { return !is_empty(); }
00204
00211 bool is_empty() const { return m_lower > m_upper; }
00212
00213
00214 static Interval const & empty()
00215 {
00216 static Interval const empty_value(value_traits::one(),-value_traits::one());
00217 return empty_value;
00218 };
00219
00220 public:
00221
00239 bool operator< (Interval const & i) const { return m_upper < i.m_lower; }
00240 bool operator> (Interval const & i) const { return m_lower > i.m_upper; }
00241 bool operator<=(Interval const & i) const { return m_upper <= i.m_lower; }
00242 bool operator>=(Interval const & i) const { return m_lower >= i.m_upper; }
00243 bool operator==(Interval const & i) const { return m_lower == i.m_lower && m_upper == i.m_upper; }
00244 bool operator!=(Interval const & i) const { return m_lower != i.m_lower || m_upper != i.m_upper; }
00245
00246 public:
00247
00255 Interval & operator+=(Interval const & i)
00256 {
00257 m_lower += i.m_lower;
00258 m_upper += i.m_upper;
00259 return (*this);
00260 }
00261
00270 Interval operator+(Interval const &i ) const { return Interval(m_lower+i.m_lower, m_upper+i.m_upper); }
00271
00279 Interval & operator-=(Interval const & i)
00280 {
00281 m_lower -= i.m_upper;
00282 m_upper -= i.m_lower;
00283 return (*this);
00284 }
00285
00294 Interval operator-(Interval const & i) const { return Interval(m_lower-i.m_upper, m_upper-i.m_lower); }
00295
00302 Interval operator-() const { return Interval(-m_upper, -m_lower); }
00303
00311 Interval & operator*=(T const & val)
00312 {
00313 if (val < value_traits::zero() )
00314 {
00315 T x = m_lower;
00316 m_lower = m_upper * val;
00317 m_upper = x * val;
00318 }
00319 else
00320 {
00321 m_upper *= val;
00322 m_lower *= val;
00323 }
00324 return (*this);
00325 }
00326
00335 Interval operator*(T const & val) const
00336 {
00337 return (val < value_traits::zero()) ? Interval(m_upper*val, m_lower*val) : Interval(m_lower*val, m_upper*val);
00338 }
00339
00347 Interval & operator*=(Interval const & i)
00348 {
00349 T tmp_lower;
00350 T tmp_upper;
00351
00352 if (m_lower <= value_traits::zero() && i.m_upper >= value_traits::zero())
00353 {
00354 tmp_lower = m_lower * i.m_upper;
00355 }
00356 else if (m_upper >= value_traits::zero())
00357 {
00358 tmp_lower = (i.m_lower <= value_traits::zero()) ? m_upper*i.m_lower : m_lower*i.m_lower;
00359 }
00360 else
00361 {
00362 tmp_lower = m_upper*i.m_upper;
00363 }
00364
00365 if (m_lower <= value_traits::zero() && i.m_lower <= value_traits::zero())
00366 {
00367 tmp_upper = m_lower * i.m_lower;
00368 }
00369 else if (m_upper >= value_traits::zero())
00370 {
00371 tmp_upper = (i.m_upper >= value_traits::zero()) ? m_upper * i.m_upper : m_lower * i.m_upper;
00372 }
00373 else
00374 {
00375 tmp_upper = m_upper * i.m_lower;
00376 }
00377
00378 m_upper = tmp_upper;
00379 m_lower = tmp_lower;
00380
00381 return *this;
00382 }
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394 Interval operator*(Interval const & i) const
00395 {
00396 Interval tmp(i);
00397 tmp *= (*this);
00398 return tmp;
00399 }
00400
00408 Interval & operator/=(Interval const & i)
00409 {
00410 assert(i.m_lower > value_traits::zero() || i.m_upper < value_traits::zero() || !"interval::operator/=(): lower must be positive or upper negative!");
00411 (*this) *= Interval(value_traits::one() / i.m_upper, value_traits::one() / i.m_lower);
00412 return (*this);
00413 }
00414
00423 Interval operator/(Interval const & i) const
00424 {
00425 assert(i.m_lower > value_traits::zero() || i.m_upper < value_traits::zero() || !"interval::operator/=(): lower must be positive or upper negative!");
00426 return (*this) * Interval(value_traits::one() / i.m_upper, value_traits::one() / i.m_lower);
00427 }
00428
00434 T get_abs_lower() const
00435 {
00436
00437
00438
00439 return (m_lower >= value_traits::zero()) ? m_lower : ( m_upper >= value_traits::zero() ? value_traits::zero() : -m_upper );
00440 }
00441
00447 T get_abs_upper() const
00448 {
00449
00450
00451
00452 return (m_lower+m_upper >= value_traits::zero()) ? m_upper : -m_lower;
00453 }
00454
00455 };
00456
00457 }
00458 }
00459 }
00460
00461
00462 #endif