-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathrect.cpp
More file actions
157 lines (132 loc) · 4.38 KB
/
rect.cpp
File metadata and controls
157 lines (132 loc) · 4.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// SPDX-License-Identifier: Apache-2.0
#include <scratchcpp/rect.h>
#include <cmath>
#include "rect_p.h"
using namespace libscratchcpp;
/*! Constructs Rect. */
Rect::Rect(double left, double top, double right, double bottom) :
impl(spimpl::make_impl<RectPrivate>(left, top, right, bottom))
{
}
/*! \copydoc Rect() */
Rect::Rect() :
impl(spimpl::make_impl<RectPrivate>())
{
}
/*! Returns the x-coordinate of the left edge. */
double Rect::left() const
{
return impl->left;
}
/*! Sets the x-coordinate of the left edge. */
void Rect::setLeft(double left)
{
impl->left = left;
}
/*! Returns the y-coordinate of the top edge. */
double Rect::top() const
{
return impl->top;
}
/*! Sets the y-coordinate of the top edge. */
void Rect::setTop(double top)
{
impl->top = top;
}
/*! Returns the x-coordinate of the right edge. */
double Rect::right() const
{
return impl->right;
}
/*! Sets the x-coordinate of the right edge. */
void Rect::setRight(double right)
{
impl->right = right;
}
/*! Returns the y-coordinate of the bottom edge. */
double Rect::bottom() const
{
return impl->bottom;
}
/*! Sets the y-coordinate of the bottom edge. */
void Rect::setBottom(double bottom)
{
impl->bottom = bottom;
}
/*! Returns the width of the rectangle. */
double Rect::width() const
{
return std::abs(impl->right - impl->left);
}
/*! Returns the height of the rectangle. */
double Rect::height() const
{
return std::abs(impl->top - impl->bottom);
}
/*! Push out the rectangle to integer bounds. */
void Rect::snapToInt()
{
// https://github.com/scratchfoundation/scratch-render/blob/c3ede9c3d54769730c7b023021511e2aba167b1f/src/Rectangle.js#L136-L141
impl->left = std::floor(impl->left);
impl->right = std::ceil(impl->right);
impl->bottom = std::floor(impl->bottom);
impl->top = std::ceil(impl->top);
}
/*! Clamps the rectangle to the given bounds. */
void Rect::clamp(double left, double top, double right, double bottom)
{
// https://github.com/scratchfoundation/scratch-render/blob/c3ede9c3d54769730c7b023021511e2aba167b1f/src/Rectangle.js#L121-L131
impl->left = std::max(impl->left, left);
impl->right = std::min(impl->right, right);
impl->bottom = std::max(impl->bottom, bottom);
impl->top = std::min(impl->top, top);
impl->left = std::min(impl->left, right);
impl->right = std::max(impl->right, left);
impl->bottom = std::min(impl->bottom, top);
impl->top = std::max(impl->top, bottom);
}
/*! Returns true if the rectangle intersects the given rectangle. */
bool Rect::intersects(const Rect &rect) const
{
// Get the sorted coordinates for the current rectangle
double x1 = std::min(impl->left, impl->right);
double x2 = std::max(impl->left, impl->right);
double y1 = std::min(impl->top, impl->bottom);
double y2 = std::max(impl->top, impl->bottom);
// Get the sorted coordinates for the other rectangle
double rectX1 = std::min(rect.impl->left, rect.impl->right);
double rectX2 = std::max(rect.impl->left, rect.impl->right);
double rectY1 = std::min(rect.impl->top, rect.impl->bottom);
double rectY2 = std::max(rect.impl->top, rect.impl->bottom);
// Check if the rectangles intersect
return !(x2 < rectX1 || rectX2 < x1 || y2 < rectY1 || rectY2 < y1);
}
/*! Returns true if the given point is inside or on the edge of the rectangle. */
bool Rect::contains(double x, double y) const
{
double bottom, top;
if (impl->top > impl->bottom) {
bottom = impl->bottom;
top = impl->top;
} else {
bottom = impl->top;
top = impl->bottom;
}
return (x >= impl->left && x <= impl->right && y >= bottom && y <= top);
}
/*! Saves the intersection of the given rectangles (in Scratch space) to dst. */
void Rect::intersected(const Rect &a, const Rect &b, Rect &dst)
{
dst.impl->left = std::max(a.impl->left, b.impl->left);
dst.impl->right = std::min(a.impl->right, b.impl->right);
dst.impl->top = std::min(a.impl->top, b.impl->top);
dst.impl->bottom = std::max(a.impl->bottom, b.impl->bottom);
}
/*! Saves the union of the given rectangles (in Scratch space) to dst. */
void Rect::united(const Rect &a, const Rect &b, Rect &dst)
{
dst.impl->left = std::min(a.impl->left, b.impl->left);
dst.impl->right = std::max(a.impl->right, b.impl->right);
dst.impl->top = std::max(a.impl->top, b.impl->top);
dst.impl->bottom = std::min(a.impl->bottom, b.impl->bottom);
}