Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
rect-test.cpp
Go to the documentation of this file.
1/*
5 * Authors:
6 * Krzysztof KosiƄski <tweenk.pl@gmail.com>
7 *
8 * Copyright 2010 Authors
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it either under the terms of the GNU Lesser General Public
12 * License version 2.1 as published by the Free Software Foundation
13 * (the "LGPL") or, at your option, under the terms of the Mozilla
14 * Public License Version 1.1 (the "MPL"). If you do not alter this
15 * notice, a recipient may use your version of this file under either
16 * the MPL or the LGPL.
17 *
18 * You should have received a copy of the LGPL along with this library
19 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * You should have received a copy of the MPL along with this library
22 * in the file COPYING-MPL-1.1
23 *
24 * The contents of this file are subject to the Mozilla Public License
25 * Version 1.1 (the "License"); you may not use this file except in
26 * compliance with the License. You may obtain a copy of the License at
27 * http://www.mozilla.org/MPL/
28 *
29 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
30 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
31 * the specific language governing rights and limitations.
32 */
33
34#include <gtest/gtest.h>
35#include <2geom/coord.h>
36#include <2geom/rect.h>
37
38namespace Geom {
39
40typedef ::testing::Types<Coord, IntCoord> CoordTypes;
41
42TEST(RectTest, Upconversion) {
43 IntRect ir(0, -27, 10, 202);
44 Rect r_a(ir);
45 Rect r_b = ir;
46 OptIntRect oir_a(ir);
47 OptIntRect oir_b = ir;
48 OptRect or_a(oir_a);
49 OptRect or_b = oir_b;
50
51 EXPECT_EQ(r_a, ir);
52 EXPECT_EQ(r_a, r_b);
53 EXPECT_EQ(r_a, *oir_a);
54 EXPECT_EQ(r_a, *oir_b);
55 EXPECT_EQ(r_a, *or_a);
56 EXPECT_EQ(r_a, *or_b);
57 EXPECT_EQ(oir_a, oir_b);
58 EXPECT_EQ(or_a, or_b);
59}
60
61TEST(RectTest, Rounding) {
62 Rect r(-0.5, -0.5, 5.5, 5.5);
63 Rect r_small(0.3, 0.0, 0.6, 10.0);
64 Rect r_int(0,0,10,10);
65 IntRect out(-1, -1, 6, 6);
66 IntRect out_small(0, 0, 1, 10);
67 IntRect out_int(0,0,10,10);
68 OptIntRect in = IntRect(0, 0, 5, 5);
69 EXPECT_EQ(r.roundOutwards(), out);
70 EXPECT_EQ(r_small.roundOutwards(), out_small);
71 EXPECT_EQ(r_int.roundOutwards(), out_int);
72 EXPECT_EQ(r.roundInwards(), in);
73 EXPECT_EQ(r_small.roundInwards(), OptIntRect());
74}
75
76TEST(RectTest, ExpansionInPlace)
77{
78 Rect r{1, 2, 3, 4};
79 r.expandBy(3);
80 EXPECT_EQ(r, Rect(1 - 3, 2 - 3, 3 + 3, 4 + 3));
81
82 Rect u{1, 2, 3, 4};
83 u.expandBy(5, 7);
84 EXPECT_EQ(u, Rect(1 - 5, 2 - 7, 3 + 5, 4 + 7));
85}
86
87TEST(RectTest, Expanded)
88{
89 EXPECT_EQ(Rect(1, 2, 3, 4).expandedBy(4), Rect(1 - 4, 2 - 4, 3 + 4, 4 + 4));
90}
91
92TEST(RectTest, ShrinkingInPlace)
93{
94 Rect r{5, 10, 15, 20};
95 r.shrinkBy(2);
96 EXPECT_EQ(r, Rect(5 + 2, 10 + 2, 15 - 2, 20 - 2));
97
98 Rect u{5, 10, 15, 20};
99 u.shrinkBy(1, 2);
100 EXPECT_EQ(u, Rect(5 + 1, 10 + 2, 15 - 1, 20 - 2));
101}
102
103TEST(RectTest, Shrunk)
104{
105 EXPECT_EQ(Rect(5, 10, 15, 20).shrunkBy(4), Rect(5 + 4, 10 + 4, 15 - 4, 20 - 4));
106}
107
108template <typename C>
109class GenericRectTest : public ::testing::Test {
110public:
111 typedef typename CoordTraits<C>::PointType CPoint;
112 typedef typename CoordTraits<C>::RectType CRect;
113 typedef typename CoordTraits<C>::OptRectType OptCRect;
114 CRect a, a2, b, c, d;
115 CRect int_ab, int_bc, uni_ab, uni_bc;
116 GenericRectTest()
117 : a(0, 0, 10, 10)
118 , a2(0, 0, 10, 10)
119 , b(-5, -5, 5, 5)
120 , c(-10, -10, -1, -1)
121 , d(1, 1, 9, 9)
122 , int_ab(0, 0, 5, 5)
123 , int_bc(-5, -5, -1, -1)
124 , uni_ab(-5, -5, 10, 10)
125 , uni_bc(-10, -10, 5, 5)
126 {}
127};
128
129TYPED_TEST_CASE(GenericRectTest, CoordTypes);
130
131TYPED_TEST(GenericRectTest, EqualityTest) {
132 typename TestFixture::CRect a(0, 0, 10, 10), a2(a), b(-5, -5, 5, 5);
133 typename TestFixture::OptCRect empty, oa = a;
134
135 EXPECT_TRUE (a == a);
136 EXPECT_FALSE(a != a);
137 EXPECT_TRUE (a == a2);
138 EXPECT_FALSE(a != a2);
139 EXPECT_TRUE (empty == empty);
140 EXPECT_FALSE(empty != empty);
141 EXPECT_FALSE(a == empty);
142 EXPECT_TRUE (a != empty);
143 EXPECT_FALSE(empty == a);
144 EXPECT_TRUE (empty != a);
145 EXPECT_FALSE(a == b);
146 EXPECT_TRUE (a != b);
147 EXPECT_TRUE (a == oa);
148 EXPECT_FALSE(a != oa);
149}
150
151TYPED_TEST(GenericRectTest, Intersects) {
152 typename TestFixture::CRect a(0, 0, 10, 10), b(-5, -5, 5, 5), c(-10, -10, -1, -1), d(1, 1, 9, 9);
153 typename TestFixture::OptCRect empty, oa(a), oc(c), od(d);
154 EXPECT_TRUE(a.intersects(a));
155 EXPECT_TRUE(a.intersects(b));
156 EXPECT_TRUE(b.intersects(a));
157 EXPECT_TRUE(b.intersects(c));
158 EXPECT_TRUE(c.intersects(b));
159 EXPECT_TRUE(a.intersects(d));
160 EXPECT_TRUE(d.intersects(a));
161 EXPECT_FALSE(a.intersects(c));
162 EXPECT_FALSE(c.intersects(a));
163 EXPECT_FALSE(c.intersects(d));
164 EXPECT_FALSE(empty.intersects(empty));
165 EXPECT_FALSE(empty.intersects(oa));
166 EXPECT_FALSE(oa.intersects(empty));
167 EXPECT_TRUE(oa.intersects(od));
168 EXPECT_FALSE(oa.intersects(oc));
169}
170
175TYPED_TEST(GenericRectTest, JonCruzRect) {
176 typename TestFixture::CRect a(10, 20, 55, 30), b(45, 20, 100,30);
177 typename TestFixture::OptCRect empty, oa(a), ob(b);
178 EXPECT_TRUE(a.intersects(a));
179 EXPECT_TRUE(a.intersects(b));
180 EXPECT_TRUE(b.intersects(a));
181 EXPECT_TRUE(oa.intersects(oa));
182 EXPECT_TRUE(oa.intersects(ob));
183 EXPECT_TRUE(ob.intersects(oa));
184}
185
186TYPED_TEST(GenericRectTest, Intersection) {
187 typename TestFixture::CRect a(0, 0, 10, 10), b(-5, -5, 5, 5), c(-10, -10, -1, -1), d(1, 1, 9, 9);
188 typename TestFixture::CRect int_ab(0, 0, 5, 5), int_bc(-5, -5, -1, -1);
189 typename TestFixture::OptCRect empty, oa(a), ob(b);
190
191 EXPECT_EQ(a & a, a);
192 EXPECT_EQ(a & b, int_ab);
193 EXPECT_EQ(b & c, int_bc);
194 EXPECT_EQ(intersect(b, c), int_bc);
195 EXPECT_EQ(intersect(a, a), a);
196 EXPECT_EQ(a & c, empty);
197 EXPECT_EQ(a & d, d);
198 EXPECT_EQ(a & empty, empty);
199 EXPECT_EQ(empty & empty, empty);
200
201 oa &= ob;
202 EXPECT_EQ(oa, int_ab);
203 oa = a;
204 oa &= b;
205 EXPECT_EQ(oa, int_ab);
206 oa = a;
207 oa &= empty;
208 EXPECT_EQ(oa, empty);
209}
210
211TYPED_TEST(GenericRectTest, Contains) {
212 typename TestFixture::CRect a(0, 0, 10, 10), b(-5, -5, 5, 5), c(-10, -10, -1, -1), d(1, 1, 9, 9);
213 typename TestFixture::CRect int_ab(0, 0, 5, 5), int_bc(-5, -5, -1, -1);
214 typename TestFixture::OptCRect empty, oa(a), od(d);
215 EXPECT_TRUE(a.contains(a));
216 EXPECT_FALSE(a.contains(b));
217 EXPECT_FALSE(b.contains(a));
218 EXPECT_FALSE(a.contains(c));
219 EXPECT_FALSE(c.contains(a));
220 EXPECT_TRUE(a.contains(d));
221 EXPECT_FALSE(d.contains(a));
222 EXPECT_TRUE(a.contains(int_ab));
223 EXPECT_TRUE(b.contains(int_ab));
224 EXPECT_TRUE(b.contains(int_bc));
225 EXPECT_TRUE(c.contains(int_bc));
226 EXPECT_FALSE(int_ab.contains(a));
227 EXPECT_FALSE(int_ab.contains(b));
228 EXPECT_FALSE(int_bc.contains(b));
229 EXPECT_FALSE(int_bc.contains(c));
230 EXPECT_FALSE(empty.contains(empty));
231 EXPECT_FALSE(empty.contains(od));
232 EXPECT_TRUE(oa.contains(empty));
233 EXPECT_TRUE(oa.contains(od));
234 EXPECT_FALSE(od.contains(oa));
235}
236
237TYPED_TEST(GenericRectTest, Union) {
238 typename TestFixture::CRect a(0, 0, 10, 10), old_a(a), b(-5, -5, 5, 5), c(-10, -10, -1, -1), d(1, 1, 9, 9);
239 typename TestFixture::CRect int_ab(0, 0, 5, 5), int_bc(-5, -5, -1, -1);
240 typename TestFixture::CRect uni_ab(-5, -5, 10, 10), uni_bc(-10, -10, 5, 5);
241 typename TestFixture::OptCRect empty, oa(a), ob(b);
242 EXPECT_EQ(a | b, uni_ab);
243 EXPECT_EQ(b | c, uni_bc);
244 EXPECT_EQ(a | a, a);
245 EXPECT_EQ(a | d, a);
246 EXPECT_EQ(a | int_ab, a);
247 EXPECT_EQ(b | int_ab, b);
248 EXPECT_EQ(uni_ab | a, uni_ab);
249 EXPECT_EQ(uni_bc | c, uni_bc);
250 EXPECT_EQ(a | empty, a);
251 EXPECT_EQ(empty | empty, empty);
252
253 a |= b;
254 EXPECT_EQ(a, uni_ab);
255 a = old_a;
256 a |= ob;
257 EXPECT_EQ(a, uni_ab);
258 a = old_a;
259 a |= empty;
260 EXPECT_EQ(a, old_a);
261 oa |= ob;
262 EXPECT_EQ(oa, uni_ab);
263 oa = old_a;
264 oa |= b;
265 EXPECT_EQ(oa, uni_ab);
266}
267
268TYPED_TEST(GenericRectTest, Area) {
269 typename TestFixture::CRect a(0, 0, 10, 10), b(-5, -5, 5, 5), c(-10, -10, -1, -1), d(1, 1, 9, 9);
270 typename TestFixture::CRect zero(0,0,0,0);
271 EXPECT_EQ(a.area(), 100);
272 EXPECT_EQ(a.area(), a.width() * a.height());
273 EXPECT_EQ(b.area(), 100);
274 EXPECT_EQ(c.area(), 81);
275 EXPECT_EQ(d.area(), 64);
276 EXPECT_FALSE(a.hasZeroArea());
277 EXPECT_TRUE(zero.hasZeroArea());
278}
279
280TYPED_TEST(GenericRectTest, Emptiness) {
281 typename TestFixture::OptCRect empty, oa(0, 0, 10, 10);
282 EXPECT_TRUE(empty.empty());
283 EXPECT_FALSE(empty);
284 EXPECT_TRUE(!empty);
285 EXPECT_FALSE(oa.empty());
286 EXPECT_TRUE(oa);
287 EXPECT_FALSE(!oa);
288}
289
290TYPED_TEST(GenericRectTest, Dimensions) {
291 typedef typename TestFixture::CPoint CPoint;
292 typename TestFixture::CRect a(-10, -20, 10, 20), b(-15, 30, 45, 90);
293 EXPECT_EQ(a.width(), 20);
294 EXPECT_EQ(a.height(), 40);
295 EXPECT_EQ(a.left(), -10);
296 EXPECT_EQ(a.top(), -20);
297 EXPECT_EQ(a.right(), 10);
298 EXPECT_EQ(a.bottom(), 20);
299 EXPECT_EQ(a.min(), CPoint(-10, -20));
300 EXPECT_EQ(a.max(), CPoint(10, 20));
301 EXPECT_EQ(a.minExtent(), a.width());
302 EXPECT_EQ(a.maxExtent(), a.height());
303 EXPECT_EQ(a.dimensions(), CPoint(20, 40));
304 EXPECT_EQ(a.midpoint(), CPoint(0, 0));
305
306 EXPECT_EQ(b.width(), 60);
307 EXPECT_EQ(b.height(), 60);
308 EXPECT_EQ(b.left(), -15);
309 EXPECT_EQ(b.top(), 30);
310 EXPECT_EQ(b.right(), 45);
311 EXPECT_EQ(b.bottom(), 90);
312 EXPECT_EQ(b.min(), CPoint(-15, 30));
313 EXPECT_EQ(b.max(), CPoint(45, 90));
314 EXPECT_EQ(b.minExtent(), b.maxExtent());
315 EXPECT_EQ(b.dimensions(), CPoint(60, 60));
316 EXPECT_EQ(b.midpoint(), CPoint(15, 60));
317}
318
319TYPED_TEST(GenericRectTest, Modification) {
320 typedef typename TestFixture::CRect CRect;
321 typedef typename TestFixture::OptCRect OptCRect;
322 typedef typename TestFixture::CPoint CPoint;
323 CRect a(-1, -1, 1, 1);
324 a.expandBy(9);
325 EXPECT_EQ(a, CRect(-10, -10, 10, 10));
326 a.setMin(CPoint(0, 0));
327 EXPECT_EQ(a, CRect(0, 0, 10, 10));
328 a.setMax(CPoint(20, 30));
329 EXPECT_EQ(a, CRect(0, 0, 20, 30));
330 a.setMax(CPoint(-5, -5));
331 EXPECT_EQ(a, CRect(-5, -5, -5, -5));
332 a.expandTo(CPoint(5, 5));
333 EXPECT_EQ(a, CRect(-5, -5, 5, 5));
334 a.expandTo(CPoint(0, 0));
335 EXPECT_EQ(a, CRect(-5, -5, 5, 5));
336 a.expandTo(CPoint(0, 15));
337 EXPECT_EQ(a, CRect(-5, -5, 5, 15));
338 a.expandBy(-10);
339 EXPECT_EQ(a, CRect(0, 5, 0, 5));
340 EXPECT_EQ(a.midpoint(), CPoint(0, 5));
341 a.unionWith(CRect(-20, 0, -10, 20));
342 EXPECT_EQ(a, CRect(-20, 0, 0, 20));
343 OptCRect oa(a);
344 oa.intersectWith(CRect(-10, -5, 5, 15));
345 EXPECT_EQ(oa, OptCRect(-10, 0, 0, 15));
346}
347
348TYPED_TEST(GenericRectTest, OptRectDereference) {
349 typename TestFixture::CRect a(0, 0, 5, 5);
350 typename TestFixture::OptCRect oa(0, 0, 10, 10);
351 EXPECT_NE(a, oa);
352 a = *oa;
353 EXPECT_EQ(a, oa);
354}
355
356TYPED_TEST(GenericRectTest, Offset) {
357 typename TestFixture::CRect a(0, 0, 5, 5), old_a(a), app1(-5, 0, 0, 5), amp1(5, 0, 10, 5),
358 app2(5, -10, 10, -5), amp2(-5, 10, 0, 15);
359 typename TestFixture::CPoint p1(-5, 0), p2(5, -10);
360 EXPECT_EQ(a + p1, app1);
361 EXPECT_EQ(a + p2, app2);
362 EXPECT_EQ(a - p1, amp1);
363 EXPECT_EQ(a - p2, amp2);
364
365 a += p1;
366 EXPECT_EQ(a, app1);
367 a = old_a;
368 a += p2;
369 EXPECT_EQ(a, app2);
370 a = old_a;
371 a -= p1;
372 EXPECT_EQ(a, amp1);
373 a = old_a;
374 a -= p2;
375 EXPECT_EQ(a, amp2);
376}
377
378TYPED_TEST(GenericRectTest, NearestEdgePoint) {
379 typename TestFixture::CRect a(0, 0, 10, 10);
380 typename TestFixture::CPoint p1(-5, 5), p2(15, 17), p3(6, 5), p4(3, 9);
381 typename TestFixture::CPoint r1(0, 5), r2(10, 10), r3(10, 5), r4(3, 10);
382
383 EXPECT_EQ(a.nearestEdgePoint(p1), r1);
384 EXPECT_EQ(a.nearestEdgePoint(p2), r2);
385 EXPECT_EQ(a.nearestEdgePoint(p3), r3);
386 EXPECT_EQ(a.nearestEdgePoint(p4), r4);
387}
388
389} // end namespace Geom
390
391/*
392 Local Variables:
393 mode:c++
394 c-file-style:"stroustrup"
395 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
396 indent-tabs-mode:nil
397 fill-column:99
398 End:
399*/
400// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
Axis-aligned generic rectangle that can be empty.
Axis aligned, non-empty, generic rectangle.
void shrinkBy(C amount)
Shrink the rectangle in both directions by the specified amount.
void expandBy(C amount)
Expand the rectangle in both directions by the specified amount.
Intersection between two shapes.
Axis-aligned rectangle that can be empty.
Definition rect.h:203
Axis aligned, non-empty rectangle.
Definition rect.h:92
OptIntRect roundInwards() const
Return the largest integer rectangle which is contained in this one.
Definition rect.h:146
IntRect roundOutwards() const
Return the smallest integer rectangle which contains this one.
Definition rect.h:141
Integral and real coordinate types and some basic utilities.
double c[8][4]
auto expandedBy(Geom::IntRect rect, int amount)
Definition geom.h:67
Various utility functions.
Definition affine.h:22
GenericRect< IntCoord > IntRect
Definition forward.h:57
TEST(AffineTest, Equality)
TYPED_TEST_CASE(GenericRectTest, CoordTypes)
::testing::Types< Coord, IntCoord > CoordTypes
Definition rect-test.cpp:40
TYPED_TEST(GenericRectTest, EqualityTest)
std::vector< Point > intersect(const xAx &C1, const xAx &C2)
Definition conicsec.cpp:361
Axis-aligned rectangle.
GenericRect< C > RectType
Definition coord.h:109
D2< C > PointType
Definition coord.h:106
GenericOptRect< C > OptRectType
Definition coord.h:110