qwt_interval.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
  2. * Qwt Widget Library
  3. * Copyright (C) 1997 Josef Wilgen
  4. * Copyright (C) 2002 Uwe Rathmann
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the Qwt License, Version 1.0
  8. *****************************************************************************/
  9. #include "qwt_interval.h"
  10. #include "qwt_math.h"
  11. #include <qalgorithms.h>
  12. /*!
  13. \brief Normalize the limits of the interval
  14. If maxValue() < minValue() the limits will be inverted.
  15. \return Normalized interval
  16. \sa isValid(), inverted()
  17. */
  18. QwtInterval QwtInterval::normalized() const
  19. {
  20. if ( d_minValue > d_maxValue )
  21. {
  22. return inverted();
  23. }
  24. if ( d_minValue == d_maxValue && d_borderFlags == ExcludeMinimum )
  25. {
  26. return inverted();
  27. }
  28. return *this;
  29. }
  30. /*!
  31. Invert the limits of the interval
  32. \return Inverted interval
  33. \sa normalized()
  34. */
  35. QwtInterval QwtInterval::inverted() const
  36. {
  37. int borderFlags = 0;
  38. if ( d_borderFlags & ExcludeMinimum )
  39. borderFlags |= ExcludeMaximum;
  40. if ( d_borderFlags & ExcludeMaximum )
  41. borderFlags |= ExcludeMinimum;
  42. return QwtInterval( d_maxValue, d_minValue, borderFlags );
  43. }
  44. /*!
  45. Test if a value is inside an interval
  46. \param value Value
  47. \return true, if value >= minValue() && value <= maxValue()
  48. */
  49. bool QwtInterval::contains( double value ) const
  50. {
  51. if ( !isValid() )
  52. return false;
  53. if ( value < d_minValue || value > d_maxValue )
  54. return false;
  55. if ( value == d_minValue && d_borderFlags & ExcludeMinimum )
  56. return false;
  57. if ( value == d_maxValue && d_borderFlags & ExcludeMaximum )
  58. return false;
  59. return true;
  60. }
  61. //! Unite 2 intervals
  62. QwtInterval QwtInterval::unite( const QwtInterval &other ) const
  63. {
  64. /*
  65. If one of the intervals is invalid return the other one.
  66. If both are invalid return an invalid default interval
  67. */
  68. if ( !isValid() )
  69. {
  70. if ( !other.isValid() )
  71. return QwtInterval();
  72. else
  73. return other;
  74. }
  75. if ( !other.isValid() )
  76. return *this;
  77. QwtInterval united;
  78. int flags = 0;
  79. // minimum
  80. if ( d_minValue < other.minValue() )
  81. {
  82. united.setMinValue( d_minValue );
  83. flags &= d_borderFlags & ExcludeMinimum;
  84. }
  85. else if ( other.minValue() < d_minValue )
  86. {
  87. united.setMinValue( other.minValue() );
  88. flags &= other.borderFlags() & ExcludeMinimum;
  89. }
  90. else // d_minValue == other.minValue()
  91. {
  92. united.setMinValue( d_minValue );
  93. flags &= ( d_borderFlags & other.borderFlags() ) & ExcludeMinimum;
  94. }
  95. // maximum
  96. if ( d_maxValue > other.maxValue() )
  97. {
  98. united.setMaxValue( d_maxValue );
  99. flags &= d_borderFlags & ExcludeMaximum;
  100. }
  101. else if ( other.maxValue() > d_maxValue )
  102. {
  103. united.setMaxValue( other.maxValue() );
  104. flags &= other.borderFlags() & ExcludeMaximum;
  105. }
  106. else // d_maxValue == other.maxValue() )
  107. {
  108. united.setMaxValue( d_maxValue );
  109. flags &= d_borderFlags & other.borderFlags() & ExcludeMaximum;
  110. }
  111. united.setBorderFlags( flags );
  112. return united;
  113. }
  114. //! Intersect 2 intervals
  115. QwtInterval QwtInterval::intersect( const QwtInterval &other ) const
  116. {
  117. if ( !other.isValid() || !isValid() )
  118. return QwtInterval();
  119. QwtInterval i1 = *this;
  120. QwtInterval i2 = other;
  121. // swap i1/i2, so that the minimum of i1
  122. // is smaller then the minimum of i2
  123. if ( i1.minValue() > i2.minValue() )
  124. {
  125. qSwap( i1, i2 );
  126. }
  127. else if ( i1.minValue() == i2.minValue() )
  128. {
  129. if ( i1.borderFlags() & ExcludeMinimum )
  130. qSwap( i1, i2 );
  131. }
  132. if ( i1.maxValue() < i2.minValue() )
  133. {
  134. return QwtInterval();
  135. }
  136. if ( i1.maxValue() == i2.minValue() )
  137. {
  138. if ( i1.borderFlags() & ExcludeMaximum ||
  139. i2.borderFlags() & ExcludeMinimum )
  140. {
  141. return QwtInterval();
  142. }
  143. }
  144. QwtInterval intersected;
  145. int flags = 0;
  146. intersected.setMinValue( i2.minValue() );
  147. flags |= i2.borderFlags() & ExcludeMinimum;
  148. if ( i1.maxValue() < i2.maxValue() )
  149. {
  150. intersected.setMaxValue( i1.maxValue() );
  151. flags |= i1.borderFlags() & ExcludeMaximum;
  152. }
  153. else if ( i2.maxValue() < i1.maxValue() )
  154. {
  155. intersected.setMaxValue( i2.maxValue() );
  156. flags |= i2.borderFlags() & ExcludeMaximum;
  157. }
  158. else // i1.maxValue() == i2.maxValue()
  159. {
  160. intersected.setMaxValue( i1.maxValue() );
  161. flags |= i1.borderFlags() & i2.borderFlags() & ExcludeMaximum;
  162. }
  163. intersected.setBorderFlags( flags );
  164. return intersected;
  165. }
  166. //! Unites this interval with the given interval.
  167. QwtInterval& QwtInterval::operator|=( const QwtInterval & interval )
  168. {
  169. *this = *this | interval;
  170. return *this;
  171. }
  172. //! Intersects this interval with the given interval.
  173. QwtInterval& QwtInterval::operator&=( const QwtInterval & interval )
  174. {
  175. *this = *this & interval;
  176. return *this;
  177. }
  178. /*!
  179. Test if two intervals overlap
  180. */
  181. bool QwtInterval::intersects( const QwtInterval &other ) const
  182. {
  183. if ( !isValid() || !other.isValid() )
  184. return false;
  185. QwtInterval i1 = *this;
  186. QwtInterval i2 = other;
  187. // swap i1/i2, so that the minimum of i1
  188. // is smaller then the minimum of i2
  189. if ( i1.minValue() > i2.minValue() )
  190. {
  191. qSwap( i1, i2 );
  192. }
  193. else if ( i1.minValue() == i2.minValue() &&
  194. i1.borderFlags() & ExcludeMinimum )
  195. {
  196. qSwap( i1, i2 );
  197. }
  198. if ( i1.maxValue() > i2.minValue() )
  199. {
  200. return true;
  201. }
  202. if ( i1.maxValue() == i2.minValue() )
  203. {
  204. return !( ( i1.borderFlags() & ExcludeMaximum ) ||
  205. ( i2.borderFlags() & ExcludeMinimum ) );
  206. }
  207. return false;
  208. }
  209. /*!
  210. Adjust the limit that is closer to value, so that value becomes
  211. the center of the interval.
  212. \param value Center
  213. \return Interval with value as center
  214. */
  215. QwtInterval QwtInterval::symmetrize( double value ) const
  216. {
  217. if ( !isValid() )
  218. return *this;
  219. const double delta =
  220. qMax( qAbs( value - d_maxValue ), qAbs( value - d_minValue ) );
  221. return QwtInterval( value - delta, value + delta );
  222. }
  223. /*!
  224. Limit the interval, keeping the border modes
  225. \param lowerBound Lower limit
  226. \param upperBound Upper limit
  227. \return Limited interval
  228. */
  229. QwtInterval QwtInterval::limited( double lowerBound, double upperBound ) const
  230. {
  231. if ( !isValid() || lowerBound > upperBound )
  232. return QwtInterval();
  233. double minValue = qMax( d_minValue, lowerBound );
  234. minValue = qMin( minValue, upperBound );
  235. double maxValue = qMax( d_maxValue, lowerBound );
  236. maxValue = qMin( maxValue, upperBound );
  237. return QwtInterval( minValue, maxValue, d_borderFlags );
  238. }
  239. /*!
  240. Extend the interval
  241. If value is below minValue, value becomes the lower limit.
  242. If value is above maxValue, value becomes the upper limit.
  243. extend has no effect for invalid intervals
  244. \param value Value
  245. \sa isValid()
  246. */
  247. QwtInterval QwtInterval::extend( double value ) const
  248. {
  249. if ( !isValid() )
  250. return *this;
  251. return QwtInterval( qMin( value, d_minValue ),
  252. qMax( value, d_maxValue ), d_borderFlags );
  253. }
  254. /*!
  255. Extend an interval
  256. \param value Value
  257. \return Reference of the extended interval
  258. \sa extend()
  259. */
  260. QwtInterval& QwtInterval::operator|=( double value )
  261. {
  262. *this = *this | value;
  263. return *this;
  264. }
  265. #ifndef QT_NO_DEBUG_STREAM
  266. QDebug operator<<( QDebug debug, const QwtInterval &interval )
  267. {
  268. const int flags = interval.borderFlags();
  269. debug.nospace() << "QwtInterval("
  270. << ( ( flags & QwtInterval::ExcludeMinimum ) ? "]" : "[" )
  271. << interval.minValue() << "," << interval.maxValue()
  272. << ( ( flags & QwtInterval::ExcludeMaximum ) ? "[" : "]" )
  273. << ")";
  274. return debug.space();
  275. }
  276. #endif