OpenTTD Source 20251005-master-ga617d009cc
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 ? this->WithX(this->right - width + 1, this->right)
215 : this->WithX(this->left, this->left + width - 1);
216 }
217
224 [[nodiscard]] inline Rect Indent(int indent, bool end) const
225 {
226 return end
227 ? this->WithX(this->left, this->right - indent)
228 : this->WithX(this->left + indent, this->right);
229 }
230
237 [[nodiscard]] inline Rect WithHeight(int height, bool end = false) const
238 {
239 return end
240 ? this->WithY(this->bottom - height + 1, this->bottom)
241 : this->WithY(this->top, 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
260 [[nodiscard]] inline Rect CentreToHeight(int height) const
261 {
262 int new_top = CentreBounds(this->top, this->bottom, height);
263 return {this->left, new_top, this->right, new_top + height - 1};
264 }
265
272 [[nodiscard]] inline Rect WithX(int new_left, int new_right) const { return {new_left, this->top, new_right, this->bottom}; }
273
280 [[nodiscard]] inline Rect WithY(int new_top, int new_bottom) const { return {this->left, new_top, this->right, new_bottom}; }
281
287 [[nodiscard]] inline Rect WithX(const Rect &other) const { return this->WithX(other.left, other.right); }
288
294 [[nodiscard]] inline Rect WithY(const Rect &other) const { return this->WithY(other.top, other.bottom); }
295};
296
302 int x = 0;
303 int y = 0;
304 int width = 0;
305 int height = 0;
306};
307
308#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.
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.
Rect CentreToHeight(int height) const
Centre a vertical dimension within this Rect.
int Height() const
Get height of Rect.
Rect WithY(int new_top, int new_bottom) const
Create a new Rect, replacing the top and bottom coordiates.
Rect WithX(int new_left, int new_right) const
Create a new Rect, replacing the left and right coordiates.
Rect WithX(const Rect &other) const
Create a new Rect, replacing the left and right coordiates.
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 WithY(const Rect &other) const
Create a new Rect, replacing the top and bottom coordiates.
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.