1 /** 2 This module contains some type definitions. 3 */ 4 module types; 5 6 /** 2D point */ 7 struct Point { 8 /// x coordinate 9 int x; 10 /// y coordinate 11 int y; 12 this(int x0, int y0) { 13 x = x0; 14 y = y0; 15 } 16 } 17 18 /** 2D rectangle */ 19 struct Rect { 20 /// x coordinate of top left corner 21 int left; 22 /// y coordinate of top left corner 23 int top; 24 /// x coordinate of bottom right corner 25 int right; 26 /// y coordinate of bottom right corner 27 int bottom; 28 /// returns average of left, right 29 @property int middlex() { return (left + right) / 2; } 30 /// returns average of top, bottom 31 @property int middley() { return (top + bottom) / 2; } 32 /// returns middle point 33 @property Point middle() { return Point(middlex, middley); } 34 /// add offset to horizontal and vertical coordinates 35 void offset(int dx, int dy) { 36 left += dx; 37 right += dx; 38 top += dy; 39 bottom += dy; 40 } 41 /// expand rectangle dimensions 42 void expand(int dx, int dy) { 43 left -= dx; 44 right += dx; 45 top -= dy; 46 bottom += dy; 47 } 48 /// shrink rectangle dimensions 49 void shrink(int dx, int dy) { 50 left += dx; 51 right -= dx; 52 top += dy; 53 bottom -= dy; 54 } 55 /// for all fields, sets this.field to rc.field if rc.field > this.field 56 void setMax(Rect rc) { 57 if (left < rc.left) 58 left = rc.left; 59 if (right < rc.right) 60 right = rc.right; 61 if (top < rc.top) 62 top = rc.top; 63 if (bottom < rc.bottom) 64 bottom = rc.bottom; 65 } 66 /// returns width of rectangle (right - left) 67 @property int width() { return right - left; } 68 /// returns height of rectangle (bottom - top) 69 @property int height() { return bottom - top; } 70 /// constructs rectangle using left, top, right, bottom coordinates 71 this(int x0, int y0, int x1, int y1) { 72 left = x0; 73 top = y0; 74 right = x1; 75 bottom = y1; 76 } 77 /// returns true if rectangle is empty (right <= left || bottom <= top) 78 @property bool empty() { 79 return right <= left || bottom <= top; 80 } 81 /// translate rectangle coordinates by (x,y) - add deltax to x coordinates, and deltay to y coordinates 82 void moveBy(int deltax, int deltay) { 83 left += deltax; 84 right += deltax; 85 top += deltay; 86 bottom += deltay; 87 } 88 /// moves this rect to fit rc bounds, retaining the same size 89 void moveToFit(ref Rect rc) { 90 if (right > rc.right) 91 moveBy(rc.right - right, 0); 92 if (bottom > rc.bottom) 93 moveBy(0, rc.bottom - bottom); 94 if (left < rc.left) 95 moveBy(rc.left - left, 0); 96 if (top < rc.top) 97 moveBy(0, rc.top - top); 98 99 } 100 /// updates this rect to intersection with rc, returns true if result is non empty 101 bool intersect(Rect rc) { 102 if (left < rc.left) 103 left = rc.left; 104 if (top < rc.top) 105 top = rc.top; 106 if (right > rc.right) 107 right = rc.right; 108 if (bottom > rc.bottom) 109 bottom = rc.bottom; 110 return right > left && bottom > top; 111 } 112 /// returns true if this rect has nonempty intersection with rc 113 bool intersects(Rect rc) { 114 if (rc.left >= right || rc.top >= bottom || rc.right <= left || rc.bottom <= top) 115 return false; 116 return true; 117 } 118 /// returns true if point is inside of this rectangle 119 bool isPointInside(Point pt) { 120 return pt.x >= left && pt.x < right && pt.y >= top && pt.y < bottom; 121 } 122 /// returns true if point is inside of this rectangle 123 bool isPointInside(int x, int y) { 124 return x >= left && x < right && y >= top && y < bottom; 125 } 126 /// this rectangle is completely inside rc 127 bool isInsideOf(Rect rc) { 128 return left >= rc.left && right <= rc.right && top >= rc.top && bottom <= rc.bottom; 129 } 130 131 bool opEquals(Rect rc) { 132 return left == rc.left && right == rc.right && top == rc.top && bottom == rc.bottom; 133 } 134 } 135