GCC Code Coverage Report


Directory: ./
File: src/2geom/parallelogram.cpp
Date: 2024-03-18 17:01:34
Exec Total Coverage
Lines: 40 55 72.7%
Functions: 7 10 70.0%
Branches: 57 120 47.5%

Line Branch Exec Source
1 /*
2 * Authors:
3 * Thomas Holder
4 * Sergei Izmailov
5 *
6 * Copyright 2020 Authors
7 *
8 * SPDX-License-Identifier: LGPL-2.1 or MPL-1.1
9 */
10
11 #include <2geom/basic-intersection.h>
12 #include <2geom/parallelogram.h>
13
14 #include <cassert>
15
16 namespace Geom {
17
18 namespace {
19 /// Return true if `p` is inside a unit rectangle
20 126 inline bool unit_rect_contains(Point const &p)
21 {
22
4/4
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 39 times.
✓ Branch 4 taken 29 times.
✓ Branch 5 taken 22 times.
267 return 0 <= p.x() && p.x() <= 1 && //
23
4/4
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 36 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 23 times.
267 0 <= p.y() && p.y() <= 1;
24 }
25
26 /// N'th corner of a unit rectangle
27 154 inline Point unit_rect_corner(unsigned i)
28 {
29
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 154 times.
154 assert(i < 4);
30 154 unsigned const y = i >> 1;
31 154 unsigned const x = (i & 1) ^ y;
32 154 return Point(x, y);
33 }
34 } // namespace
35
36 92 Point Parallelogram::corner(unsigned i) const
37 {
38
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 92 times.
92 assert(i < 4);
39
1/2
✓ Branch 3 taken 92 times.
✗ Branch 4 not taken.
184 return unit_rect_corner(i) * m_affine;
40 }
41
42 1 Rect Parallelogram::bounds() const
43 {
44
3/6
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
1 Rect rect(corner(0), corner(2));
45
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 rect.expandTo(corner(1));
46
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 rect.expandTo(corner(3));
47 1 return rect;
48 }
49
50 17 bool Parallelogram::intersects(Parallelogram const &other) const
51 {
52
5/10
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 17 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 17 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 17 times.
17 if (m_affine.isSingular() || other.m_affine.isSingular()) {
53 return false;
54 }
55
56
2/4
✓ Branch 3 taken 17 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 17 times.
✗ Branch 7 not taken.
17 auto const affine1 = other.m_affine * m_affine.inverse();
57
1/2
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
17 auto const affine2 = affine1.inverse();
58
59 // case 1: any corner inside the other rectangle
60
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 14 times.
76 for (unsigned i = 0; i != 4; ++i) {
61 62 auto const p = unit_rect_corner(i);
62
7/12
✓ Branch 2 taken 62 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 59 times.
✓ Branch 6 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 59 times.
✓ Branch 10 taken 62 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 3 times.
✓ Branch 14 taken 59 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
183 if (unit_rect_contains(p * affine1) || //
63
3/6
✓ Branch 1 taken 59 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 59 times.
✓ Branch 5 taken 3 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
121 unit_rect_contains(p * affine2)) {
64 3 return true;
65 }
66 }
67
68 // case 2: any sides intersect (check diagonals)
69
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 3 times.
20 for (unsigned i = 0; i != 2; ++i) {
70
1/2
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
17 auto const A = corner(i);
71
1/2
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
17 auto const B = corner((i + 2) % 4);
72
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 6 times.
33 for (unsigned j = 0; j != 2; ++j) {
73
1/2
✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
27 auto const C = other.corner(j);
74
1/2
✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
27 auto const D = other.corner((j + 2) % 4);
75
3/4
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
✓ Branch 4 taken 16 times.
27 if (non_collinear_segments_intersect(A, B, C, D)) {
76 11 return true;
77 }
78 }
79 }
80
81 3 return false;
82 }
83
84 5 bool Parallelogram::contains(Point const &p) const
85 {
86
4/6
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 2 times.
10 return !m_affine.isSingular() && //
87
4/12
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 5 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 5 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 5 times.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
15 unit_rect_contains(p * m_affine.inverse());
88 }
89
90 bool Parallelogram::contains(Parallelogram const &other) const
91 {
92 if (m_affine.isSingular()) {
93 return false;
94 }
95
96 auto const inv = m_affine.inverse();
97
98 for (unsigned i = 0; i != 4; ++i) {
99 if (!unit_rect_contains(other.corner(i) * inv)) {
100 return false;
101 }
102 }
103
104 return true;
105 }
106
107 Coord Parallelogram::minExtent() const
108 {
109 return std::min(m_affine.expansionX(), //
110 m_affine.expansionY());
111 }
112
113 Coord Parallelogram::maxExtent() const
114 {
115 return std::max(m_affine.expansionX(), //
116 m_affine.expansionY());
117 }
118
119 3 bool Parallelogram::isSheared(Coord eps) const
120 {
121
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
9 return !are_near(dot(m_affine.xAxis(), m_affine.yAxis()), //
122 12 0.0, eps);
123 }
124
125 } // namespace Geom
126
127 /*
128 Local Variables:
129 mode:c++
130 c-file-style:"stroustrup"
131 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
132 indent-tabs-mode:nil
133 fill-column:99
134 End:
135 */
136 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
137