OpenTTD Source 20250818-master-g1850ad1aa2
geometry_type.hpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10#ifndef GEOMETRY_TYPE_HPP
11#define GEOMETRY_TYPE_HPP
12
13#if defined(__APPLE__)
14 /* Mac OS X already has both Rect and Point declared */
15# define Rect OTTD_Rect
16# define Point OTTD_Point
17#endif /* __APPLE__ */
18
26inline int CentreBounds(int min, int max, int size)
27{
28 return (min + max - size + 1) / 2;
29}
30
32template <typename T>
33struct Coord2D {
34 T x = 0;
35 T y = 0;
36
37 constexpr Coord2D() = default;
38 constexpr Coord2D(T x, T y) : x(x), y(y) {}
39};
40
42template <typename T>
43struct Coord3D {
44 T x = 0;
45 T y = 0;
46 T z = 0;
47
48 constexpr Coord3D() = default;
49 constexpr Coord3D(T x, T y, T z) : x(x), y(y), z(z) {}
50};
51
54
56struct Dimension {
57 uint width;
58 uint height;
59
60 constexpr Dimension() : width(0), height(0) {}
61 constexpr Dimension(uint w, uint h) : width(w), height(h) {}
62
63 bool operator< (const Dimension &other) const
64 {
65 int x = (*this).width - other.width;
66 if (x != 0) return x < 0;
67 return (*this).height < other.height;
68 }
69
70 bool operator== (const Dimension &other) const
71 {
72 return (*this).width == other.width && (*this).height == other.height;
73 }
74};
75
78 uint8_t left = 0;
79 uint8_t top = 0;
80 uint8_t right = 0;
81 uint8_t bottom = 0;
82
83 static const RectPadding zero;
84
89 constexpr uint Horizontal() const { return this->left + this->right; }
90
95 constexpr uint Vertical() const { return this->top + this->bottom; }
96};
97
98inline const RectPadding RectPadding::zero{};
99
101struct Rect {
102 int left = 0;
103 int top = 0;
104 int right = 0;
105 int bottom = 0;
106
111 inline int Width() const { return this->right - this->left + 1; }
112
117 inline int Height() const { return this->bottom - this->top + 1; }
118
124 [[nodiscard]] inline Rect Shrink(int s) const
125 {
126 return {this->left + s, this->top + s, this->right - s, this->bottom - s};
127 }
128
135 [[nodiscard]] inline Rect Shrink(int h, int v) const
136 {
137 return {this->left + h, this->top + v, this->right - h, this->bottom - v};
138 }
139
148 [[nodiscard]] inline Rect Shrink(int left, int top, int right, int bottom) const
149 {
150 return {this->left + left, this->top + top, this->right - right, this->bottom - bottom};
151 }
152
158 [[nodiscard]] inline Rect Shrink(const RectPadding &other) const
159 {
160 return {this->left + other.left, this->top + other.top, this->right - other.right, this->bottom - other.bottom};
161 }
162
169 [[nodiscard]] inline Rect Shrink(const RectPadding &horz, const RectPadding &vert) const
170 {
171 return {this->left + horz.left, this->top + vert.top, this->right - horz.right, this->bottom - vert.bottom};
172 }
173
179 [[nodiscard]] inline Rect Expand(int s) const
180 {
181 return this->Shrink(-s);
182 }
183
189 [[nodiscard]] inline Rect Expand(const RectPadding &other) const
190 {
191 return {this->left - other.left, this->top - other.top, this->right + other.right, this->bottom + other.bottom};
192 }
193
200 [[nodiscard]] inline Rect Translate(int x, int y) const
201 {
202 return {this->left + x, this->top + y, this->right + x, this->bottom + y};
203 }
204
211 [[nodiscard]] inline Rect WithWidth(int width, bool end) const
212 {
213 return end
214 ? Rect {this->right - width + 1, this->top, this->right, this->bottom}
215 : Rect {this->left, this->top, this->left + width - 1, this->bottom};
216 }
217
224 [[nodiscard]] inline Rect Indent(int indent, bool end) const
225 {
226 return end
227 ? Rect {this->left, this->top, this->right - indent, this->bottom}
228 : Rect {this->left + indent, this->top, this->right, this->bottom};
229 }
230
237 [[nodiscard]] inline Rect WithHeight(int height, bool end = false) const
238 {
239 return end
240 ? Rect {this->left, this->bottom - height + 1, this->right, this->bottom}
241 : Rect {this->left, this->top, this->right, this->top + height - 1};
242 }
243
249 inline bool Contains(const Point &pt) const
250 {
251 /* This is a local version of IsInsideMM, to avoid including math_func everywhere. */
252 return (uint)(pt.x - this->left) <= (uint)(this->right - this->left) && (uint)(pt.y - this->top) <= (uint)(this->bottom - this->top);
253 }
254
261 [[nodiscard]] inline Rect CentreTo(int width, int height) const
262 {
263 int new_left = CentreBounds(this->left, this->right, width);
264 int new_right = CentreBounds(this->top, this->bottom, height);
265 return {new_left, new_right, new_left + width, new_right + height};
266 }
267};
268
274 int x = 0;
275 int y = 0;
276 int width = 0;
277 int height = 0;
278};
279
280#endif /* GEOMETRY_TYPE_HPP */
int CentreBounds(int min, int max, int size)
Determine where to position a centred object.
A coordinate with two dimensons.
T y
Y coordinate.
T x
X coordinate.
A coordinate with three dimensions.
T x
X coordinate.
T y
Y coordinate.
T z
Z coordinate.
Dimensions (a width and height) of a rectangle in 2D.
Specification of a rectangle with an absolute top-left coordinate and a (relative) width/height.
Padding dimensions to apply to each side of a Rect.
constexpr uint Horizontal() const
Get total horizontal padding of RectPadding.
constexpr uint Vertical() const
Get total vertical padding of RectPadding.
Specification of a rectangle with absolute coordinates of all edges.
Rect WithWidth(int width, bool end) const
Copy Rect and set its width.
Rect CentreTo(int width, int height) const
Centre a dimension within this Rect.
int Width() const
Get width of Rect.
Rect Expand(const RectPadding &other) const
Copy and expand Rect by a RectPadding.
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
Rect Shrink(const RectPadding &other) const
Copy and shrink Rect by a RectPadding.
Rect WithHeight(int height, bool end=false) const
Copy Rect and set its height.
Rect Indent(int indent, bool end) const
Copy Rect and indent it from its position.
int Height() const
Get height of Rect.
Rect Shrink(int h, int v) const
Copy and shrink Rect by h horizontal and v vertical pixels.
Rect Translate(int x, int y) const
Copy and translate Rect by x,y pixels.
Rect Shrink(int left, int top, int right, int bottom) const
Copy and shrink Rect by pixels.
Rect Shrink(const RectPadding &horz, const RectPadding &vert) const
Copy and shrink Rect by a different horizontal and vertical RectPadding.
bool Contains(const Point &pt) const
Test if a point falls inside this Rect.
Rect Expand(int s) const
Copy and expand Rect by s pixels.