1 module d2d.core.utils;
2 
3 import gl3n.linalg;
4 
5 struct Rectangle(T)
6 {
7 	alias vec2t = Vector!(T, 2);
8 
9 	T x = 0, y = 0, width = 0, height = 0;
10 
11 	vec2t center() const @property nothrow @nogc pure @safe
12 	{
13 		return vec2t(x + width / 2, y + height / 2);
14 	}
15 
16 	vec2t size() const @property nothrow @nogc pure @safe
17 	{
18 		return vec2t(width, height);
19 	}
20 
21 	vec2t size(vec2t newSize) @property nothrow @nogc pure @safe
22 	{
23 		width = newSize.x;
24 		height = newSize.y;
25 		return newSize;
26 	}
27 
28 	Rectangle!T normalized() const @property nothrow @nogc pure @safe
29 	{
30 		Rectangle!T copy = this;
31 		if (copy.width < 0)
32 		{
33 			copy.x += copy.width;
34 			copy.width = -copy.width;
35 		}
36 		if (copy.height < 0)
37 		{
38 			copy.y += copy.height;
39 			copy.height = -copy.height;
40 		}
41 		return copy;
42 	}
43 
44 	Rectangle!T scale(vec2t size) const @property nothrow @nogc pure @safe
45 	{
46 		return scale(size.x, size.y);
47 	}
48 
49 	Rectangle!T scale(T x, T y) const @property nothrow @nogc pure @safe
50 	{
51 		return Rectangle!T(this.x * x, this.y * y, width * x, height * y);
52 	}
53 
54 	static Rectangle!T dim(T width, T height) nothrow @nogc pure @safe
55 	{
56 		return Rectangle!T(0, 0, width, height);
57 	}
58 
59 	static Rectangle!T dim(vec2t size) nothrow @nogc pure @safe
60 	{
61 		return Rectangle!T(0, 0, size.x, size.y);
62 	}
63 
64 	static Rectangle!T dim(T x, T y, T width, T height) nothrow @nogc pure @safe
65 	{
66 		return Rectangle!T(x, y, width, height);
67 	}
68 
69 	static Rectangle!T dim(vec2t pos, T width, T height) nothrow @nogc pure @safe
70 	{
71 		return Rectangle!T(pos.x, pos.y, width, height);
72 	}
73 
74 	static Rectangle!T dim(T x, T y, vec2t size) nothrow @nogc pure @safe
75 	{
76 		return Rectangle!T(x, y, size.x, size.y);
77 	}
78 
79 	static Rectangle!T dim(vec2t pos, vec2t size) nothrow @nogc pure @safe
80 	{
81 		return Rectangle!T(pos.x, pos.y, size.x, size.y);
82 	}
83 
84 	static Rectangle!T abs(T x1, T y1, T x2, T y2) nothrow @nogc pure @safe
85 	{
86 		return Rectangle!T(x1, y1, x2 - x1, y2 - y1);
87 	}
88 
89 	static Rectangle!T abs(vec2t pos1, T x2, T y2) nothrow @nogc pure @safe
90 	{
91 		return Rectangle!T(pos1.x, pos1.y, x2 - pos1.x, y2 - pos1.y);
92 	}
93 
94 	static Rectangle!T abs(T x1, T y1, vec2t pos2) nothrow @nogc pure @safe
95 	{
96 		return Rectangle!T(x1, y1, pos2.x - x1, pos2.y - y1);
97 	}
98 
99 	static Rectangle!T abs(vec2t pos1, vec2t pos2) nothrow @nogc pure @safe
100 	{
101 		return Rectangle!T(pos1.x, pos1.y, pos2.x - pos1.x, pos2.y - pos1.y);
102 	}
103 
104 	vec2t pos00() @property const nothrow @nogc pure @safe
105 	{
106 		return vec2t(x, y);
107 	}
108 
109 	vec2t pos10() @property const nothrow @nogc pure @safe
110 	{
111 		return vec2t(x + width, y);
112 	}
113 
114 	vec2t pos11() @property const nothrow @nogc pure @safe
115 	{
116 		return vec2t(x + width, y + height);
117 	}
118 
119 	vec2t pos01() @property const nothrow @nogc pure @safe
120 	{
121 		return vec2t(x, y + height);
122 	}
123 
124 	Rectangle!T translate(T x, T y) nothrow @nogc pure @safe
125 	{
126 		return Rectangle!T(this.x + x, this.y + y, width, height);
127 	}
128 
129 	Rectangle!T translate(vec2t position) nothrow @nogc pure @safe
130 	{
131 		return Rectangle!T(x + position.x, y + position.y, width, height);
132 	}
133 
134 	bool intersects(const rect other) nothrow @nogc pure @safe
135 	{
136 		return !(x + width < other.x || other.x + other.width < x || y + height < other.y
137 				|| other.y + other.height < y);
138 	}
139 }
140 
141 alias rect = Rectangle!float;
142 alias rectd = Rectangle!double;
143 alias recti = Rectangle!int;