1 module polyplex.math.rectangle; 2 import polyplex.math; 3 import std.traits; 4 5 /// Base template for all AABB-types. 6 /// Params: 7 /// type = all values get stored as this type 8 struct RectangleT(T) if (isNumeric!T) { 9 public: 10 union { 11 struct { 12 /// X coordinate of the top-left corner of the rectangle 13 T X = 0; 14 15 /// Y coordinate of the top-left corner of the rectangle 16 T Y = 0; 17 18 /// The width of the rectangle 19 T Width = 0; 20 21 /// The height of the rectangle 22 T Height = 0; 23 24 } 25 26 /// Rectangle represented as an array, useful for passing data to the graphics API 27 T[4] data; 28 } 29 30 /// Constructor 31 this(W, H)(W width, H height) if (isNumeric!W && isNumeric!H) { 32 this.Width = cast(T)width; 33 this.Height = cast(T)height; 34 } 35 36 /// Constructor 37 this(X, Y, W, H)(X x, Y y, W width, H height) if (isNumeric!X && isNumeric!Y && isNumeric!W && isNumeric!H) { 38 this.X = cast(T)x; 39 this.Y = cast(T)y; 40 this.Width = cast(T)width; 41 this.Height = cast(T)height; 42 } 43 44 @trusted RectangleT!T opBinary(string op, T)(T other) if (isNumeric!(T)) { 45 import std.format; 46 mixin(q{ 47 return Rectangle( 48 X %1$s cast(T)other, 49 Y %1$s cast(T)other, 50 Width %1$s cast(T)other, 51 Height %1$s cast(T)other); 52 }.format(op)); 53 } 54 55 @trusted RectangleT!T opBinary(string op, T)(T other) if (IsRectangleT!T) { 56 import std.format; 57 mixin(q{ 58 return Rectangle( 59 X %1$s cast(T)other.X, 60 Y %1$s cast(T)other.Y, 61 Width %1$s cast(T)other.Width, 62 Height %1$s cast(T)other.Height); 63 }.format(op)); 64 } 65 66 /** 67 Gets the X coordinate of the left side of the rectangle 68 */ 69 T Left() { return this.X; } 70 71 /** 72 Gets the X coordinate of the right side of the rectangle 73 */ 74 T Right() { return this.X + this.Width; } 75 76 /** 77 Gets the Y coordinate of the top of the rectangle 78 */ 79 T Top() { return this.Y; } 80 81 /** 82 Gets the Y coordinate of the bottom of the rectangle 83 */ 84 T Bottom() { return this.Y + this.Height; } 85 86 /** 87 Gets the center of the rectangle (as floats) 88 */ 89 Vector2 Center() { return Vector2(this.X + (this.Width/2), this.Y + (this.Height/2)); } 90 91 /** 92 Gets wether this rectangle intersects another 93 */ 94 bool Intersects(T)(T other) if (IsRectangleT!T) { 95 bool v = (other.Left >= this.Right || other.Right <= this.Left || other.Top >= this.Bottom || other.Bottom <= this.Top); 96 return !v; 97 } 98 99 /** 100 Gets wether a 2D vector is intersecting this rectangle 101 */ 102 bool Intersects(U)(U other) if (IsVector2T!U) { 103 bool v = (other.X >= this.Right || other.X < this.Left || other.Y >= this.Bottom || other.Y < this.Top); 104 return !v; 105 } 106 107 /** 108 Returns a displaced version of this rectangle 109 */ 110 RectangleT!T Displace(T x, T y) { 111 return RectangleT!T(this.X+x, this.Y+y, this.Width, this.Height); 112 } 113 114 /** 115 Returns an expanded version of this rectangle 116 */ 117 RectangleT!T Expand(T)(T x, T y) { 118 return RectangleT!T(this.X-x, this.Y-y, this.Width+(x*2), this.Height+(y*2)); 119 } 120 } 121 122 // Checks wether a type is a rectangle type 123 enum IsRectangleT(T) = is(T : RectangleT!U, U...); 124 125 alias Rectangle = RectangleT!float; 126 alias Rectanglei = RectangleT!int;