Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #ifndef INCLUDED_BASEGFX_RANGE_B2DRANGE_HXX
21 : #define INCLUDED_BASEGFX_RANGE_B2DRANGE_HXX
22 :
23 : #include <ostream>
24 : #include <vector>
25 :
26 : #include <basegfx/vector/b2dvector.hxx>
27 : #include <basegfx/point/b2dpoint.hxx>
28 : #include <basegfx/tuple/b2dtuple.hxx>
29 : #include <basegfx/range/basicrange.hxx>
30 : #include <basegfx/basegfxdllapi.h>
31 :
32 : namespace basegfx
33 : {
34 : // predeclarations
35 : class B2IRange;
36 : class B2DHomMatrix;
37 :
38 : /** A two-dimensional interval over doubles
39 :
40 : This is a set of real numbers, bounded by a lower and an upper
41 : pair. All inbetween values are included in the set (see also
42 : http://en.wikipedia.org/wiki/Interval_%28mathematics%29).
43 :
44 : The set is closed, i.e. the upper and the lower bound are
45 : included (if you're used to the notation - we're talking about
46 : [a,b] here, compared to half-open [a,b) or open intervals
47 : (a,b)).
48 :
49 : That means, isInside(val) will return true also for values of
50 : val=a or val=b.
51 :
52 : @see B1DRange
53 : */
54 : class B2DRange
55 : {
56 : public:
57 : typedef double ValueType;
58 : typedef DoubleTraits TraitsType;
59 :
60 0 : B2DRange() {}
61 :
62 : /// Create degenerate interval consisting of a single point
63 0 : explicit B2DRange(const B2DTuple& rTuple)
64 : : maRangeX(rTuple.getX()),
65 0 : maRangeY(rTuple.getY())
66 : {
67 0 : }
68 :
69 : /// Create proper interval between the two given double pairs
70 0 : B2DRange(double x1,
71 : double y1,
72 : double x2,
73 : double y2)
74 : : maRangeX(x1),
75 0 : maRangeY(y1)
76 : {
77 0 : maRangeX.expand(x2);
78 0 : maRangeY.expand(y2);
79 0 : }
80 :
81 : /// Create proper interval between the two given points
82 0 : B2DRange(const B2DTuple& rTuple1,
83 : const B2DTuple& rTuple2)
84 : : maRangeX(rTuple1.getX()),
85 0 : maRangeY(rTuple1.getY())
86 : {
87 0 : expand( rTuple2 );
88 0 : }
89 :
90 : BASEGFX_DLLPUBLIC explicit B2DRange(const B2IRange& rRange);
91 :
92 : /** Check if the interval set is empty
93 :
94 : @return false, if no value is in this set - having a
95 : single point included will already return true.
96 : */
97 0 : bool isEmpty() const
98 : {
99 : return (
100 0 : maRangeX.isEmpty()
101 0 : || maRangeY.isEmpty()
102 0 : );
103 : }
104 :
105 : /// reset the object to empty state again, clearing all values
106 0 : void reset()
107 : {
108 0 : maRangeX.reset();
109 0 : maRangeY.reset();
110 0 : }
111 :
112 0 : bool operator==( const B2DRange& rRange ) const
113 : {
114 0 : return (maRangeX == rRange.maRangeX
115 0 : && maRangeY == rRange.maRangeY);
116 : }
117 :
118 0 : bool operator!=( const B2DRange& rRange ) const
119 : {
120 0 : return (maRangeX != rRange.maRangeX
121 0 : || maRangeY != rRange.maRangeY);
122 : }
123 :
124 0 : bool equal(const B2DRange& rRange) const
125 : {
126 0 : return (maRangeX.equal(rRange.maRangeX)
127 0 : && maRangeY.equal(rRange.maRangeY));
128 : }
129 :
130 : /// get lower bound of the set. returns arbitrary values for empty sets.
131 0 : double getMinX() const
132 : {
133 0 : return maRangeX.getMinimum();
134 : }
135 :
136 : /// get lower bound of the set. returns arbitrary values for empty sets.
137 0 : double getMinY() const
138 : {
139 0 : return maRangeY.getMinimum();
140 : }
141 :
142 : /// get upper bound of the set. returns arbitrary values for empty sets.
143 0 : double getMaxX() const
144 : {
145 0 : return maRangeX.getMaximum();
146 : }
147 :
148 : /// get upper bound of the set. returns arbitrary values for empty sets.
149 0 : double getMaxY() const
150 : {
151 0 : return maRangeY.getMaximum();
152 : }
153 :
154 : /// return difference between upper and lower X value. returns 0 for empty sets.
155 0 : double getWidth() const
156 : {
157 0 : return maRangeX.getRange();
158 : }
159 :
160 : /// return difference between upper and lower Y value. returns 0 for empty sets.
161 0 : double getHeight() const
162 : {
163 0 : return maRangeY.getRange();
164 : }
165 :
166 : /// get lower bound of the set. returns arbitrary values for empty sets.
167 0 : B2DPoint getMinimum() const
168 : {
169 : return B2DPoint(
170 : maRangeX.getMinimum(),
171 : maRangeY.getMinimum()
172 0 : );
173 : }
174 :
175 : /// get upper bound of the set. returns arbitrary values for empty sets.
176 0 : B2DPoint getMaximum() const
177 : {
178 : return B2DPoint(
179 : maRangeX.getMaximum(),
180 : maRangeY.getMaximum()
181 0 : );
182 : }
183 :
184 : /// return difference between upper and lower point. returns (0,0) for empty sets.
185 0 : B2DVector getRange() const
186 : {
187 : return B2DVector(
188 : maRangeX.getRange(),
189 : maRangeY.getRange()
190 0 : );
191 : }
192 :
193 : /// return center point of set. returns (0,0) for empty sets.
194 0 : B2DPoint getCenter() const
195 : {
196 : return B2DPoint(
197 : maRangeX.getCenter(),
198 : maRangeY.getCenter()
199 0 : );
200 : }
201 :
202 : /// return center X value of set. returns 0 for empty sets.
203 0 : double getCenterX() const
204 : {
205 0 : return maRangeX.getCenter();
206 : }
207 :
208 : /// return center Y value of set. returns 0 for empty sets.
209 0 : double getCenterY() const
210 : {
211 0 : return maRangeY.getCenter();
212 : }
213 :
214 : /// yields true if given point is contained in set
215 0 : bool isInside(const B2DTuple& rTuple) const
216 : {
217 : return (
218 0 : maRangeX.isInside(rTuple.getX())
219 0 : && maRangeY.isInside(rTuple.getY())
220 0 : );
221 : }
222 :
223 : /// yields true if rRange is inside, or equal to set
224 0 : bool isInside(const B2DRange& rRange) const
225 : {
226 : return (
227 0 : maRangeX.isInside(rRange.maRangeX)
228 0 : && maRangeY.isInside(rRange.maRangeY)
229 0 : );
230 : }
231 :
232 : /// yields true if rRange at least partly inside set
233 0 : bool overlaps(const B2DRange& rRange) const
234 : {
235 : return (
236 0 : maRangeX.overlaps(rRange.maRangeX)
237 0 : && maRangeY.overlaps(rRange.maRangeY)
238 0 : );
239 : }
240 :
241 : /// yields true if overlaps(rRange) does, and the overlap is larger than infinitesimal
242 0 : bool overlapsMore(const B2DRange& rRange) const
243 : {
244 : return (
245 0 : maRangeX.overlapsMore(rRange.maRangeX)
246 0 : && maRangeY.overlapsMore(rRange.maRangeY)
247 0 : );
248 : }
249 :
250 : /// add point to the set, expanding as necessary
251 0 : void expand(const B2DTuple& rTuple)
252 : {
253 0 : maRangeX.expand(rTuple.getX());
254 0 : maRangeY.expand(rTuple.getY());
255 0 : }
256 :
257 : /// add rRange to the set, expanding as necessary
258 0 : void expand(const B2DRange& rRange)
259 : {
260 0 : maRangeX.expand(rRange.maRangeX);
261 0 : maRangeY.expand(rRange.maRangeY);
262 0 : }
263 :
264 : /// calc set intersection
265 0 : void intersect(const B2DRange& rRange)
266 : {
267 0 : maRangeX.intersect(rRange.maRangeX);
268 0 : maRangeY.intersect(rRange.maRangeY);
269 0 : }
270 :
271 : /// grow set by fValue on all sides
272 0 : void grow(double fValue)
273 : {
274 0 : maRangeX.grow(fValue);
275 0 : maRangeY.grow(fValue);
276 0 : }
277 :
278 : BASEGFX_DLLPUBLIC void transform(const B2DHomMatrix& rMatrix);
279 :
280 : private:
281 : typedef ::basegfx::BasicRange< ValueType, TraitsType > MyBasicRange;
282 :
283 : MyBasicRange maRangeX;
284 : MyBasicRange maRangeY;
285 : };
286 :
287 : /** Round double to nearest integer for 2D range
288 :
289 : @return the nearest integer for this range
290 : */
291 : BASEGFX_DLLPUBLIC B2IRange fround(const B2DRange& rRange);
292 :
293 : /** Compute the set difference of the two given ranges
294 :
295 : This method calculates the symmetric difference (aka XOR)
296 : between the two given ranges, and returning the resulting
297 : ranges. Thus, the result will contain all areas where one, but
298 : not both ranges lie.
299 :
300 : @param o_rResult
301 : Result vector. The up to four difference ranges are returned
302 : within this vector
303 :
304 : @param rFirst
305 : The first range
306 :
307 : @param rSecond
308 : The second range
309 :
310 : @return the input vector
311 : */
312 : BASEGFX_DLLPUBLIC ::std::vector< B2DRange >& computeSetDifference( ::std::vector< B2DRange >& o_rResult,
313 : const B2DRange& rFirst,
314 : const B2DRange& rSecond );
315 :
316 : } // end of namespace basegfx
317 :
318 :
319 : template< typename charT, typename traits >
320 : inline std::basic_ostream<charT, traits> & operator <<(
321 : std::basic_ostream<charT, traits> & stream, const basegfx::B2DRange& range )
322 : {
323 : return stream << range.getWidth() << "x" << range.getHeight() << "@" << range.getMinimum();
324 : }
325 :
326 : #endif // INCLUDED_BASEGFX_RANGE_B2DRANGE_HXX
327 :
328 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|