Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
parallelogram.cpp
Go to the documentation of this file.
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
12#include <2geom/parallelogram.h>
13
14#include <cassert>
15
16namespace Geom {
17
18namespace {
20inline bool unit_rect_contains(Point const &p)
21{
22 return 0 <= p.x() && p.x() <= 1 && //
23 0 <= p.y() && p.y() <= 1;
24}
25
27inline Point unit_rect_corner(unsigned i)
28{
29 assert(i < 4);
30 unsigned const y = i >> 1;
31 unsigned const x = (i & 1) ^ y;
32 return Point(x, y);
33}
34} // namespace
35
37{
38 assert(i < 4);
39 return unit_rect_corner(i) * m_affine;
40}
41
43{
44 Rect rect(corner(0), corner(2));
45 rect.expandTo(corner(1));
46 rect.expandTo(corner(3));
47 return rect;
48}
49
51{
52 if (m_affine.isSingular() || other.m_affine.isSingular()) {
53 return false;
54 }
55
56 auto const affine1 = other.m_affine * m_affine.inverse();
57 auto const affine2 = affine1.inverse();
58
59 // case 1: any corner inside the other rectangle
60 for (unsigned i = 0; i != 4; ++i) {
61 auto const p = unit_rect_corner(i);
62 if (unit_rect_contains(p * affine1) || //
63 unit_rect_contains(p * affine2)) {
64 return true;
65 }
66 }
67
68 // case 2: any sides intersect (check diagonals)
69 for (unsigned i = 0; i != 2; ++i) {
70 auto const A = corner(i);
71 auto const B = corner((i + 2) % 4);
72 for (unsigned j = 0; j != 2; ++j) {
73 auto const C = other.corner(j);
74 auto const D = other.corner((j + 2) % 4);
75 if (non_collinear_segments_intersect(A, B, C, D)) {
76 return true;
77 }
78 }
79 }
80
81 return false;
82}
83
84bool Parallelogram::contains(Point const &p) const
85{
86 return !m_affine.isSingular() && //
87 unit_rect_contains(p * m_affine.inverse());
88}
89
90bool 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
108{
109 return std::min(m_affine.expansionX(), //
111}
112
114{
115 return std::max(m_affine.expansionX(), //
117}
118
120{
121 return !are_near(dot(m_affine.xAxis(), m_affine.yAxis()), //
122 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 :
pair< double, double > Point
Definition parser.cpp:7
Basic intersection routines.
Point yAxis() const
Definition affine.cpp:36
Coord expansionX() const
Calculates the amount of x-scaling imparted by the Affine.
Definition affine.cpp:64
bool isSingular(Coord eps=EPSILON) const
Check whether this matrix is singular.
Definition affine.cpp:377
Point xAxis() const
Definition affine.cpp:32
Affine inverse() const
Compute the inverse matrix.
Definition affine.cpp:388
Coord expansionY() const
Calculates the amount of y-scaling imparted by the Affine.
Definition affine.cpp:71
void expandTo(CPoint const &p)
Enlarge the rectangle to contain the given point.
Paralellogram, representing a linear transformation of a rectangle.
bool isSheared(Coord eps=EPSILON) const
True if this parallelogram does not have right angles.
Rect bounds() const
Axis-aligned bounding box.
Point corner(unsigned i) const
bool contains(Point const &) const
Coord maxExtent() const
Returns longer side length.
bool intersects(Parallelogram const &) const
Coord minExtent() const
Returns shorter side length.
Two-dimensional point that doubles as a vector.
Definition point.h:66
Axis aligned, non-empty rectangle.
Definition rect.h:92
double Coord
Floating point type used to store coordinates.
Definition coord.h:76
Various utility functions.
Definition affine.h:22
bool non_collinear_segments_intersect(const Point &A, const Point &B, const Point &C, const Point &D)
Check if two line segments intersect.
T dot(D2< T > const &a, D2< T > const &b)
Definition d2.h:355
bool are_near(Affine const &a1, Affine const &a2, Coord eps=EPSILON)