labplot  2.8.2
About: LabPlot is an application for plotting and analysis of 2D and 3D functions and data. It is a complete rewrite of LabPlot1 and lacks in the first release a lot of features available in the predecessor. On the other hand, the GUI and the usability is more superior.
  Fossies Dox: labplot-2.8.2.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

Interval.h
Go to the documentation of this file.
1 /***************************************************************************
2  File : Interval.h
3  Project : LabPlot
4  --------------------------------------------------------------------
5  Copyright : (C) 2007 by Tilman Benkert (thzs@gmx.net)
6  Copyright : (C) 2007 by Knut Franke (knut.franke@gmx.de)
7  Copyright : (C) 2012 by Alexander Semke (alexander.semke@web.de)
8  Description : Auxiliary class for interval based data
9 
10  ***************************************************************************/
11 
12 /***************************************************************************
13  * *
14  * This program is free software; you can redistribute it and/or modify *
15  * it under the terms of the GNU General Public License as published by *
16  * the Free Software Foundation; either version 2 of the License, or *
17  * (at your option) any later version. *
18  * *
19  * This program is distributed in the hope that it will be useful, *
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22  * GNU General Public License for more details. *
23  * *
24  * You should have received a copy of the GNU General Public License *
25  * along with this program; if not, write to the Free Software *
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
27  * Boston, MA 02110-1301 USA *
28  * *
29  ***************************************************************************/
30 
31 #ifndef INTERVAL_H
32 #define INTERVAL_H
33 
35 
36 extern "C" {
37 #include "backend/nsl/nsl_math.h"
38 }
39 
40 template<class T> class Interval;
41 
42 template<class T> class IntervalBase {
43  public:
44  IntervalBase() : m_start(-1), m_end(-1){}
46  m_start = start;
47  m_end = end;
48  }
49  virtual ~IntervalBase() = default;
50  T start() const { return m_start; }
51  T end() const { return m_end; }
52  void setStart(T start) { m_start = start; }
53  void setEnd(T end) { m_end = end; }
54  bool contains(const Interval<T>& other) const { return ( m_start <= other.start() && m_end >= other.end() ); }
55  bool contains(T value) const { return ( m_start <= value && m_end >= value ); }
56  bool fuzzyContains(T value) const {
57  bool rc1 = nsl_math_definitely_less_than(m_start, value);
58  bool rc2 = nsl_math_definitely_greater_than(m_end, value);
59  return (rc1 && rc2);
60  }
61  bool intersects(const Interval<T>& other) const { return ( contains(other.start()) || contains(other.end()) ); }
62  //! Return the intersection of two intervals
63  /**
64  * This function returns an invalid interval if the two intervals do not intersect.
65  */
66  static Interval<T> intersection(const Interval<T>& first, const Interval<T>& second)
67  {
68  return Interval<T>( qMax(first.start(), second.start()), qMin(first.end(), second.end()) );
69  }
70  void translate(T offset) { m_start += offset; m_end += offset; }
71  bool operator==(const Interval<T>& other) const { return ( m_start == other.start() && m_end == other.end() ); }
73  m_start = other.start();
74  m_end = other.end();
75  return *this;
76  }
77  //! Returns true if no gap is between two intervals.
78  virtual bool touches(const Interval<T>& other) const = 0;
79  //! Merge two intervals that touch or intersect
80  static Interval<T> merge(const Interval<T>& a, const Interval<T>& b) {
81  if( !(a.intersects(b) || a.touches(b)) )
82  return a;
83  return Interval<T>( qMin(a.start(), b.start()), qMax(a.end(), b.end()) );
84  }
85  //! Subtract an interval from another
86  static QVector< Interval<T> > subtract(const Interval<T>& src_iv, const Interval<T>& minus_iv) {
87  QVector< Interval<T> > list;
88  if( (src_iv == minus_iv) || (minus_iv.contains(src_iv)) )
89  return list;
90 
91  if( !src_iv.intersects(minus_iv) )
92  list.append(src_iv);
93  else if( src_iv.end() <= minus_iv.end() )
94  list.append( Interval<T>(src_iv.start(), minus_iv.start()-1) );
95  else if( src_iv.start() >= minus_iv.start() )
96  list.append( Interval<T>(minus_iv.end()+1, src_iv.end()) );
97  else {
98  list.append( Interval<T>(src_iv.start(), minus_iv.start()-1) );
99  list.append( Interval<T>(minus_iv.end()+1, src_iv.end()) );
100  }
101 
102  return list;
103  }
104  //! Split an interval into two
105  static QVector< Interval<T> > split(const Interval<T>& i, T before) {
106  QVector< Interval<T> > list;
107  if( before < i.start() || before > i.end() )
108  {
109  list.append(i);
110  }
111  else
112  {
113  Interval<T> left(i.start(), before-1);
114  Interval<T> right(before, i.end());
115  if(left.isValid())
116  list.append(left);
117  if(right.isValid())
118  list.append(right);
119  }
120  return list;
121  }
122  //! Merge an interval into a list
123  /*
124  * This function merges all intervals in the list until none of them
125  * intersect or touch anymore.
126  */
128  for(int c=0; c<list->size(); c++)
129  {
130  if( list->at(c).touches(i) || list->at(c).intersects(i) )
131  {
132  Interval<T> result = merge(list->takeAt(c), i);
133  mergeIntervalIntoList(list, result);
134  return;
135  }
136  }
137  list->append(i);
138  }
139  //! Restrict all intervals in the list to their intersection with a given interval
140  /**
141  * Remark: This may decrease the list size.
142  */
143  static void restrictList(QVector< Interval<T> > * list, Interval<T> i)
144  {
145  Interval<T> temp;
146  for(int c=0; c<list->size(); c++)
147  {
148  temp = intersection(list->at(c), i);
149  if(!temp.isValid())
150  list->removeAt(c--);
151  else
152  list->replace(c, temp);
153  }
154 
155  }
156  //! Subtract an interval from all intervals in the list
157  /**
158  * Remark: This may increase or decrease the list size.
159  */
161  QVector< Interval<T> > temp_list;
162  for(int c=0; c<list->size(); c++)
163  {
164  temp_list = subtract(list->at(c), i);
165  if(temp_list.isEmpty())
166  list->removeAt(c--);
167  else
168  {
169  list->replace(c, temp_list.at(0));
170  if(temp_list.size()>1)
171  list->insert(c, temp_list.at(1));
172  }
173  }
174  }
176  QVector< Interval<T> > *tmp1, *tmp2;
177  tmp1 = new QVector< Interval<T> >();
178  *tmp1 << *static_cast< Interval<T>* >(this);
179  foreach(Interval<T> i, subtrahend) {
180  tmp2 = new QVector< Interval<T> >();
181  foreach(Interval<T> j, *tmp1)
182  *tmp2 << subtract(j, i);
183  delete tmp1;
184  tmp1 = tmp2;
185  }
186  QVector< Interval<T> > result = *tmp1;
187  delete tmp1;
188  return result;
189  }
190 
191  //! Return a string in the format '[start,end]'
192  QString toString() const {
193  return "[" + QString::number(m_start) + "," + QString::number(m_end) + "]";
194  }
195 
196  protected:
197  //! Interval start
199  //! Interval end
200  T m_end;
201 };
202 
203 //! Auxiliary class for interval based data
204 /**
205  * This class represents an interval of
206  * the type [start,end]. It should be pretty
207  * self explanatory.
208  *
209  * For the template argument (T), only numerical types ((unsigned) short, (unsigned) int,
210  * (unsigned) long, float, double, long double) are supported.
211  */
212 template<class T> class Interval : public IntervalBase<T> {
213  public:
214  Interval() = default;
216  Interval(const Interval<T>&) = default;
217  T size() const {
219  }
220  bool isValid() const {
221  return ( IntervalBase<T>::m_start >= 0 && IntervalBase<T>::m_end >= 0 &&
223  }
224  bool touches(const Interval<T>& other) const override {
225  return ( (other.end() == IntervalBase<T>::m_start-1) ||
226  (other.start() == IntervalBase<T>::m_end+1) );
227  }
228 };
229 
230 template<> class Interval<float> : public IntervalBase<float> {
231  public:
232  Interval() {}
233  Interval(float start, float end) : IntervalBase<float>(start, end) {}
234  Interval(const Interval<float>& other) = default;
237  bool touches(const Interval<float>& other) const override {
238  return ( (other.end() == IntervalBase<float>::m_start) ||
239  (other.start() == IntervalBase<float>::m_end) );
240  }
241 };
242 
243 template<> class Interval<double> : public IntervalBase<double> {
244  public:
245  Interval() {}
246  Interval(double start, double end) : IntervalBase<double>(start, end) {}
247  Interval(const Interval<double>&) = default;
250  bool touches(const Interval<double>& other) const override {
251  return ( (other.end() == IntervalBase<double>::m_start) ||
252  (other.start() == IntervalBase<double>::m_end) );
253  }
254 };
255 
256 template<> class Interval<long double> : public IntervalBase<long double> {
257  public:
258  Interval() {}
259  Interval(long double start, long double end) : IntervalBase<long double>(start, end) {}
260  Interval(const Interval<long double>& other) = default;
263  bool touches(const Interval<long double>& other) const override {
264  return ( (other.end() == IntervalBase<long double>::m_start) ||
266  }
267 };
268 
269 #endif
270 
static void restrictList(QVector< Interval< T > > *list, Interval< T > i)
Restrict all intervals in the list to their intersection with a given interval.
Definition: Interval.h:143
void setEnd(T end)
Definition: Interval.h:53
T m_start
Interval start.
Definition: Interval.h:198
static void mergeIntervalIntoList(QVector< Interval< T > > *list, Interval< T > i)
Merge an interval into a list.
Definition: Interval.h:127
bool contains(const Interval< T > &other) const
Definition: Interval.h:54
void setStart(T start)
Definition: Interval.h:52
static Interval< T > intersection(const Interval< T > &first, const Interval< T > &second)
Return the intersection of two intervals.
Definition: Interval.h:66
void translate(T offset)
Definition: Interval.h:70
T start() const
Definition: Interval.h:50
static QVector< Interval< T > > split(const Interval< T > &i, T before)
Split an interval into two.
Definition: Interval.h:105
bool fuzzyContains(T value) const
Definition: Interval.h:56
T m_end
Interval end.
Definition: Interval.h:200
bool contains(T value) const
Definition: Interval.h:55
static QVector< Interval< T > > subtract(const Interval< T > &src_iv, const Interval< T > &minus_iv)
Subtract an interval from another.
Definition: Interval.h:86
QVector< Interval< T > > operator-(QVector< Interval< T > > subtrahend)
Definition: Interval.h:175
virtual bool touches(const Interval< T > &other) const =0
Returns true if no gap is between two intervals.
Interval< T > & operator=(const Interval< T > &other)
Definition: Interval.h:72
static Interval< T > merge(const Interval< T > &a, const Interval< T > &b)
Merge two intervals that touch or intersect.
Definition: Interval.h:80
QString toString() const
Return a string in the format '[start,end]'.
Definition: Interval.h:192
bool operator==(const Interval< T > &other) const
Definition: Interval.h:71
virtual ~IntervalBase()=default
bool intersects(const Interval< T > &other) const
Definition: Interval.h:61
static void subtractIntervalFromList(QVector< Interval< T > > *list, Interval< T > i)
Subtract an interval from all intervals in the list.
Definition: Interval.h:160
IntervalBase(T start, T end)
Definition: Interval.h:45
T end() const
Definition: Interval.h:51
IntervalBase()
Definition: Interval.h:44
bool isValid() const
Definition: Interval.h:249
Interval(double start, double end)
Definition: Interval.h:246
Interval(const Interval< double > &)=default
double size() const
Definition: Interval.h:248
bool touches(const Interval< double > &other) const override
Returns true if no gap is between two intervals.
Definition: Interval.h:250
bool isValid() const
Definition: Interval.h:236
float size() const
Definition: Interval.h:235
Interval(float start, float end)
Definition: Interval.h:233
bool touches(const Interval< float > &other) const override
Returns true if no gap is between two intervals.
Definition: Interval.h:237
Interval(const Interval< float > &other)=default
bool touches(const Interval< long double > &other) const override
Returns true if no gap is between two intervals.
Definition: Interval.h:263
Interval(const Interval< long double > &other)=default
Interval(long double start, long double end)
Definition: Interval.h:259
bool isValid() const
Definition: Interval.h:262
long double size() const
Definition: Interval.h:261
Auxiliary class for interval based data.
Definition: Interval.h:212
T size() const
Definition: Interval.h:217
bool touches(const Interval< T > &other) const override
Returns true if no gap is between two intervals.
Definition: Interval.h:224
Interval(T start, T end)
Definition: Interval.h:215
Interval(const Interval< T > &)=default
bool isValid() const
Definition: Interval.h:220
Interval()=default
bool nsl_math_definitely_greater_than(double a, double b)
Definition: nsl_math.c:48
bool nsl_math_definitely_less_than(double a, double b)
Definition: nsl_math.c:56