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