~centralelyon2010/inkscape/imagelinks2

« back to all changes in this revision

Viewing changes to src/2geom/interval.h

  • Committer: Ted Gould
  • Date: 2008-11-21 05:24:08 UTC
  • Revision ID: ted@canonical.com-20081121052408-tilucis2pjrrpzxx
MergeĀ fromĀ fe-moved

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
 
45
45
namespace Geom {
46
46
 
47
 
/* Although an Interval where _b[0] > _b[1] is considered empty, for proper functioning of other methods,
48
 
 * a proper empty Interval is [+infinity, -infinity]. Then, expandTo(p) will set the interval to [p,p].
 
47
class Interval;
 
48
 
 
49
/** 
 
50
 * \brief This class represents a range of numbers that is never empty.
 
51
 *
 
52
 * The endpoints are included in the range.
49
53
 */
50
54
class Interval {
51
55
private:
52
56
    Coord _b[2];
53
57
 
54
58
public:
55
 
    // The default constructor creates an empty interval, that ranges from +infinity to -infinity.
56
 
    // Doing an expandTo(p) on this empty interval will correctly set the whole interval to [p,p].
57
 
    explicit Interval() { _b[0] = +infinity();  _b[1] = -infinity(); }
 
59
    /// The default constructor creates an interval [0,0]  DO NOT RELY ON THIS, BEST NOT TO USE THIS CONSTRUCTOR
 
60
    explicit Interval() { _b[0] = 0;  _b[1] = 0; }
58
61
    explicit Interval(Coord u) { _b[0] = _b[1] = u; }
59
62
    /* When creating an Interval using the constructor specifying the exact range, the created interval
60
63
     * will be [u,v] when u<=v ; and will be [v,u] when v < u !!!
78
81
    inline Coord extent() const { return _b[1] - _b[0]; }
79
82
    inline Coord middle() const { return (_b[1] + _b[0]) * 0.5; }
80
83
    
81
 
    inline bool isEmpty() const { return _b[0] > _b[1]; }
 
84
//    inline bool isEmpty() const { return _b[0] > _b[1]; }
 
85
    inline bool isSingular() const { return _b[0] == _b[1]; }
82
86
    inline bool contains(Coord val) const { return _b[0] <= val && val <= _b[1]; }
83
87
    bool contains(const Interval & val) const { return _b[0] <= val._b[0] && val._b[1] <= _b[1]; }
84
88
    bool intersects(const Interval & val) const {
167
171
        return result;
168
172
    }
169
173
    
 
174
    /** When this would create an empty interval, the interval will be the centerpoint of the old range only.
 
175
     */
170
176
    inline void expandBy(double amnt) {
171
177
        _b[0] -= amnt;
172
178
        _b[1] += amnt;
 
179
        if (_b[0] > _b[1]) {
 
180
            Coord halfway = (_b[0]+_b[1])/2;
 
181
            _b[0] = _b[1] = halfway;
 
182
        }
173
183
    }
174
184
    
175
185
    inline void unionWith(const Interval & a) {
214
224
    return Interval(std::min(a.min(), b.min()),
215
225
                    std::max(a.max(), b.max()));
216
226
}
217
 
inline boost::optional<Interval> intersect(const Interval & a, const Interval & b) {
 
227
 
 
228
/**
 
229
 * \brief OptInterval is an Interval that can be empty.
 
230
 */
 
231
class OptInterval : public boost::optional<Interval> {
 
232
public:
 
233
    OptInterval() : boost::optional<Interval>() {};
 
234
    OptInterval(Interval const &a) : boost::optional<Interval>(a) {};
 
235
    OptInterval(Coord u) : boost::optional<Interval>(Interval(u)) {};
 
236
    OptInterval(Coord u, Coord v) : boost::optional<Interval>(Interval(u,v)) {};
 
237
 
 
238
    /**
 
239
     * Check whether this OptInterval is empty or not.
 
240
     */
 
241
    inline bool isEmpty() { return (*this == false); };
 
242
    
 
243
    /**
 
244
     * If \c this is empty, copy argument \c a. Otherwise, union with it (and do nothing when \c a is empty)
 
245
     */
 
246
    inline void unionWith(const OptInterval & a) {
 
247
        if (a) {
 
248
            if (*this) { // check that we are not empty
 
249
                (*this)->unionWith(*a);
 
250
            } else {
 
251
                *this = a;
 
252
            }
 
253
        }
 
254
    }
 
255
};
 
256
 
 
257
inline OptInterval intersect(const Interval & a, const Interval & b) {
218
258
    Coord u = std::max(a.min(), b.min()),
219
259
          v = std::min(a.max(), b.max());
220
260
    //technically >= might be incorrect, but singulars suck
221
 
    return u >= v ? boost::optional<Interval>()
222
 
                  : boost::optional<Interval>(Interval(u, v));
 
261
    return u >= v ? OptInterval()
 
262
                  : OptInterval(Interval(u, v));
223
263
}
224
264
 
225
265
}