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 
10 #include <qglobal.h>
11 #if QT_VERSION >= 0x040000
12 #include <qalgorithms.h>
13 #else
14 #include <qtl.h>
15 #endif
16 
17 #include "qwt_math.h"
18 #include "qwt_double_interval.h"
19 
20 /*!
21    \brief Normalize the limits of the interval
22 
23    If maxValue() < minValue() the limits will be inverted.
24    \return Normalized interval
25 
26    \sa isValid(), inverted()
27 */
28 QwtDoubleInterval QwtDoubleInterval::normalized() const
29 {
30     if ( d_minValue > d_maxValue )
31     {
32         return inverted();
33     }
34     if ( d_minValue == d_maxValue && d_borderFlags == ExcludeMinimum )
35     {
36         return inverted();
37     }
38 
39     return *this;
40 }
41 
42 /*!
43    Invert the limits of the interval
44    \return Inverted interval
45    \sa normalized()
46 */
47 QwtDoubleInterval QwtDoubleInterval::inverted() const
48 {
49     int borderFlags = 0;
50     if ( d_borderFlags & ExcludeMinimum )
51         borderFlags |= ExcludeMaximum;
52     if ( d_borderFlags & ExcludeMaximum )
53         borderFlags |= ExcludeMinimum;
54 
55     return QwtDoubleInterval(d_maxValue, d_minValue, borderFlags);
56 }
57 
58 /*!
59   Test if a value is inside an interval
60 
61   \param value Value
62   \return true, if value >= minValue() && value <= maxValue()
63 */
64 bool QwtDoubleInterval::contains(double value) const
65 {
66     if ( !isValid() )
67         return false;
68 
69     if ( value < d_minValue || value > d_maxValue )
70         return false;
71 
72     if ( value == d_minValue && d_borderFlags & ExcludeMinimum )
73         return false;
74 
75     if ( value == d_maxValue && d_borderFlags & ExcludeMaximum )
76         return false;
77 
78     return true;
79 }
xt_event_prepare(GSource * source_data,gint * timeout)80 
81 //! Unite 2 intervals
82 QwtDoubleInterval QwtDoubleInterval::unite(
83     const QwtDoubleInterval &other) const
84 {
85     /*
86      If one of the intervals is invalid return the other one.
87      If both are invalid return an invalid default interval
88      */
89     if ( !isValid() )
90     {
91         if ( !other.isValid() )
92             return QwtDoubleInterval();
93         else
94             return other;
95     }
96     if ( !other.isValid() )
97         return *this;
98 
99     QwtDoubleInterval united;
100     int flags = 0;
101 
102     // minimum
103     if ( d_minValue < other.minValue() )
104     {
105         united.setMinValue(d_minValue);
106         flags &= d_borderFlags & ExcludeMinimum;
107     }
108     else if ( other.minValue() < d_minValue )
109     {
110         united.setMinValue(other.minValue());
111         flags &= other.borderFlags() & ExcludeMinimum;
112     }
113     else // d_minValue == other.minValue()
114     {
115         united.setMinValue(d_minValue);
116         flags &= (d_borderFlags & other.borderFlags()) & ExcludeMinimum;
117     }
118 
119     // maximum
120     if ( d_maxValue > other.maxValue() )
121     {
122         united.setMaxValue(d_maxValue);
123         flags &= d_borderFlags & ExcludeMaximum;
124     }
125     else if ( other.maxValue() > d_maxValue )
126     {
127         united.setMaxValue(other.maxValue());
128         flags &= other.borderFlags() & ExcludeMaximum;
129     }
130     else // d_maxValue == other.maxValue() )
131     {
132         united.setMaxValue(d_maxValue);
133         flags &= d_borderFlags & other.borderFlags() & ExcludeMaximum;
134     }
135 
136     united.setBorderFlags(flags);
137     return united;
138 }
139 
140 //! Intersect 2 intervals
141 QwtDoubleInterval QwtDoubleInterval::intersect(
142     const QwtDoubleInterval &other) const
143 {
144     if ( !other.isValid() || !isValid() )
145         return QwtDoubleInterval();
146 
147     QwtDoubleInterval i1 = *this;
148     QwtDoubleInterval i2 = other;
149 
150     // swap i1/i2, so that the minimum of i1
151     // is smaller then the minimum of i2
152 
153     if ( i1.minValue() > i2.minValue() )
154     {
gtk_xtbin_get_type(void)155         qSwap(i1, i2);
156     }
157     else if ( i1.minValue() == i2.minValue() )
158     {
159         if ( i1.borderFlags() & ExcludeMinimum )
160             qSwap(i1, i2);
161     }
162 
163     if ( i1.maxValue() < i2.minValue() )
164     {
165         return QwtDoubleInterval();
166     }
167 
168     if ( i1.maxValue() == i2.minValue() )
169     {
170         if ( i1.borderFlags() & ExcludeMaximum ||
171             i2.borderFlags() & ExcludeMinimum )
172         {
173             return QwtDoubleInterval();
174         }
175     }
176 
177     QwtDoubleInterval intersected;
178     int flags = 0;
179 
gtk_xtbin_class_init(GtkXtBinClass * klass)180     intersected.setMinValue(i2.minValue());
181     flags |= i2.borderFlags() & ExcludeMinimum;
182 
183     if ( i1.maxValue() < i2.maxValue() )
184     {
185         intersected.setMaxValue(i1.maxValue());
186         flags |= i1.borderFlags() & ExcludeMaximum;
187     }
188     else if ( i2.maxValue() < i1.maxValue() )
189     {
190         intersected.setMaxValue(i2.maxValue());
191         flags |= i2.borderFlags() & ExcludeMaximum;
192     }
193     else // i1.maxValue() == i2.maxValue()
194     {
195         intersected.setMaxValue(i1.maxValue() );
gtk_xtbin_init(GtkXtBin * xtbin)196         flags |= i1.borderFlags() & i2.borderFlags() & ExcludeMaximum;
197     }
198 
199     intersected.setBorderFlags(flags);
200     return intersected;
201 }
202 
203 //! Unites this interval with the given interval.
gtk_xtbin_realize(GtkWidget * widget)204 QwtDoubleInterval& QwtDoubleInterval::operator|=(
205     const QwtDoubleInterval &interval)
206 {
207     *this = *this | interval;
208     return *this;
209 }
210 
211 //! Intersects this interval with the given interval.
212 QwtDoubleInterval& QwtDoubleInterval::operator&=(
213     const QwtDoubleInterval &interval)
214 {
215     *this = *this & interval;
216     return *this;
217 }
218 
219 /*!
220    Test if two intervals overlap
221 */
222 bool QwtDoubleInterval::intersects(const QwtDoubleInterval &other) const
223 {
224     if ( !isValid() || !other.isValid() )
225         return false;
226 
227     QwtDoubleInterval i1 = *this;
228     QwtDoubleInterval i2 = other;
229 
230     // swap i1/i2, so that the minimum of i1
231     // is smaller then the minimum of i2
232 
233     if ( i1.minValue() > i2.minValue() )
234     {
235         qSwap(i1, i2);
236     }
237     else if ( i1.minValue() == i2.minValue() &&
238             i1.borderFlags() & ExcludeMinimum )
239     {
240         qSwap(i1, i2);
241     }
242 
243     if ( i1.maxValue() > i2.minValue() )
244     {
245         return true;
gtk_xtbin_new(GdkWindow * parent_window,String * f)246     }
247     if ( i1.maxValue() == i2.minValue() )
248     {
249         return !( (i1.borderFlags() & ExcludeMaximum) ||
250             (i2.borderFlags() & ExcludeMinimum) );
251     }
252     return false;
253 }
254 
255 /*!
256    Adjust the limit that is closer to value, so that value becomes
257    the center of the interval.
258 
259    \param value Center
260    \return Interval with value as center
261 */
262 QwtDoubleInterval QwtDoubleInterval::symmetrize(double value) const
263 {
264     if ( !isValid() )
265         return *this;
266 
267     const double delta =
268         qwtMax(qwtAbs(value - d_maxValue), qwtAbs(value - d_minValue));
269 
270     return QwtDoubleInterval(value - delta, value + delta);
271 }
272 
273 /*!
274    Limit the interval, keeping the border modes
275 
276    \param lowerBound Lower limit
277    \param upperBound Upper limit
278 
279    \return Limited interval
280 */
281 QwtDoubleInterval QwtDoubleInterval::limited(
282     double lowerBound, double upperBound) const
283 {
284     if ( !isValid() || lowerBound > upperBound )
285         return QwtDoubleInterval();
286 
287     double minValue = qwtMax(d_minValue, lowerBound);
288     minValue = qwtMin(minValue, upperBound);
289 
290     double maxValue = qwtMax(d_maxValue, lowerBound);
291     maxValue = qwtMin(maxValue, upperBound);
292 
293     return QwtDoubleInterval(minValue, maxValue, d_borderFlags);
294 }
295 
296 /*!
297    Extend the interval
298 
299    If value is below minValue, value becomes the lower limit.
300    If value is above maxValue, value becomes the upper limit.
301 
gtk_xtbin_unrealize(GtkWidget * object)302    extend has no effect for invalid intervals
303 
304    \param value Value
305    \sa isValid()
306 */
307 QwtDoubleInterval QwtDoubleInterval::extend(double value) const
308 {
309     if ( !isValid() )
310         return *this;
311 
312     return QwtDoubleInterval( qwtMin(value, d_minValue),
313         qwtMax(value, d_maxValue), d_borderFlags );
314 }
315 
316 QwtDoubleInterval& QwtDoubleInterval::operator|=(double value)
317 {
318     *this = *this | value;
319     return *this;
320 }
321