1 module prova.math.rect; 2 3 import prova.math, 4 std.math; 5 6 /// 7 enum Side { LEFT, RIGHT, TOP, BOTTOM } 8 9 /// 10 struct Rect 11 { 12 /// 13 float left = 0; 14 /// 15 float top = 0; 16 /// 17 float width = 0; 18 /// 19 float height = 0; 20 21 /// 22 this(float left, float top, float width, float height) 23 { 24 set(left, top, width, height); 25 } 26 27 //// Sets the position and dimensions of the rect in a single statement 28 void set(float left, float top, float width, float height) 29 { 30 this.left = left; 31 this.top = top; 32 this.width = width; 33 this.height = height; 34 } 35 36 /// 37 @property float right() const 38 { 39 return left + width; 40 } 41 42 /// 43 @property void right(float value) 44 { 45 left = value - width; 46 } 47 48 /// 49 @property float bottom() const 50 { 51 return top - height; 52 } 53 54 /// 55 @property void bottom(float value) 56 { 57 top = value + height; 58 } 59 60 /// 61 Vector2 getSize() const 62 { 63 return Vector2(width, height); 64 } 65 66 /// 67 Vector2 getCenter() const 68 { 69 return Vector2(left + width / 2, top - height / 2); 70 } 71 72 /// 73 Vector2 getTopLeft() const 74 { 75 return Vector2(left, top); 76 } 77 78 /// 79 Vector2 getTopRight() const 80 { 81 return Vector2(right, top); 82 } 83 84 /// 85 Vector2 getBottomLeft() const 86 { 87 return Vector2(left, bottom); 88 } 89 90 /// 91 Vector2 getBottomRight() const 92 { 93 return Vector2(right, bottom); 94 } 95 96 /// 97 Side getClosestSide(Rect rect) const 98 { 99 const Vector2 center = getCenter(); 100 const Vector2 rectCenter = rect.getCenter(); 101 102 return getClosestSide( 103 (rectCenter.x - center.x) / (width + rect.width), 104 (rectCenter.y - center.y) / (height + rect.height) 105 ); 106 } 107 108 /// 109 Side getClosestSide(Vector2 position) const 110 { 111 const Vector2 center = getCenter(); 112 113 return getClosestSide( 114 (position.x - center.x) / width, 115 (position.y - center.y) / height 116 ); 117 } 118 119 private Side getClosestSide(float fractionX, float fractionY) const 120 { 121 if(abs(fractionX) > abs(fractionY)) { 122 if(fractionX > 0) 123 return Side.RIGHT; 124 if(fractionX < 0) 125 return Side.LEFT; 126 } else { 127 if(fractionY > 0) 128 return Side.TOP; 129 if(fractionY < 0) 130 return Side.BOTTOM; 131 } 132 133 // default to the left side 134 return Side.LEFT; 135 } 136 }