1 module polyplex.math.rectangle;
2 import polyplex.math;
3 
4 /// Base template for all AABB-types.
5 /// Params:
6 /// type = all values get stored as this type
7 class Rectangle {
8 public:
9 	int X = 0;
10 	int Y = 0;
11 	int Width = 0;
12 	int Height = 0;
13 
14 	this() { }
15 
16 	this(int width, int height) {
17 		this.X = 0;
18 		this.Y = 0;
19 		this.Width = width;
20 		this.Height = height;
21 	}
22 
23 	this(int x, int y, int width, int height) {
24 		this.X = x;
25 		this.Y = y;
26 		this.Width = width;
27 		this.Height = height;
28 	}
29 
30 	import std.traits;
31 	@trusted Rectangle opBinary(string op, T)(T other) if (isNumeric!(T)) {
32 		import std.format;
33 		mixin(q{
34 			return new Rectangle(X %s other, Y %s other, Width %s other, Height %s other);
35 		}.format(op, op, op, op));
36 	}
37 
38 	@trusted Rectangle opBinary(string op, T)(T other) if (is(T : Rectangle)) {
39 		import std.format;
40 		mixin(q{
41 			return new Rectangle(X %s other.X, Y %s other.Y, Width %s other.Width, Height %s other.Height);
42 		}.format(op, op, op, op));
43 	}
44 
45 	int Left() { return this.X; }
46 	int Right() { return this.X + this.Width; }
47 	int Top() { return this.Y; }
48 	int Bottom() { return this.Y + this.Height; }
49 	Vector2 Center() { return Vector2(this.X + (this.Width/2), this.Y + (this.Height/2)); }
50 
51 	bool Intersects(Rectangle other) {
52 		if (other is null) return false;
53 		bool v = (other.Left > this.Right || other.Right < this.Left || other.Top > this.Bottom || other.Bottom < this.Top);
54 		return !v;
55 	}
56 
57 	bool Intersects(Vector2 other) {
58 		bool v = (other.X > this.Right || other.X < this.Left || other.Y > this.Bottom || other.Y < this.Top);
59 		return !v;
60 	}
61 
62 	Rectangle Displace(int x, int y) {
63 		return new Rectangle(this.X+x, this.Y+y, this.Width, this.Height);
64 	}
65 
66 	Rectangle Expand(int x, int y) {
67 		return new Rectangle(this.X-x, this.Y-y, this.Width+x, this.Height+y);
68 	}
69 }