1 /* 2 ******************************************************************************************* 3 * Dgame (a D game framework) - Copyright (c) Randy Schütt 4 * 5 * This software is provided 'as-is', without any express or implied warranty. 6 * In no event will the authors be held liable for any damages arising from 7 * the use of this software. 8 * 9 * Permission is granted to anyone to use this software for any purpose, 10 * including commercial applications, and to alter it and redistribute it 11 * freely, subject to the following restrictions: 12 * 13 * 1. The origin of this software must not be misrepresented; you must not claim 14 * that you wrote the original software. If you use this software in a product, 15 * an acknowledgment in the product documentation would be appreciated but is 16 * not required. 17 * 18 * 2. Altered source versions must be plainly marked as such, and must not be 19 * misrepresented as being the original software. 20 * 21 * 3. This notice may not be removed or altered from any source distribution. 22 ******************************************************************************************* 23 */ 24 module Dgame.Math.Circle; 25 26 private: 27 28 import derelict.sdl2.sdl; 29 30 import Dgame.Math.Vector2; 31 32 import std.math: sqrt; 33 34 35 public: 36 37 /** 38 * Circle defines a circle structure. 39 * 40 * Author: Leonardo Tada 41 */ 42 struct Circle { 43 44 /** 45 * The x coordinate 46 */ 47 int x = 0; 48 /** 49 * The y coordinates 50 */ 51 int y = 0; 52 /** 53 * The radius 54 */ 55 uint radius; 56 57 /** 58 * CTor 59 */ 60 @nogc 61 this(int x, int y, uint radius) pure nothrow { 62 this.x = x; 63 this.y = y; 64 this.radius = radius; 65 } 66 67 /** 68 * Supported operations: +, -, *, /, % 69 */ 70 @nogc 71 Circle opBinary(string op)(const Circle circle) const pure nothrow { 72 switch (op) { 73 case "+": 74 case "-": 75 case "*": 76 case "/": 77 case "%": 78 mixin("return Circle(this.x " ~ op ~ " circle.x, 79 this.y " ~ op ~ " circle.y, 80 this.radius " ~ op ~ " circle.radius;"); 81 default: 82 assert(0, "Unsupported Operation: " ~ op); 83 } 84 } 85 86 /** 87 * Collapse this Circle. Means that the radius is set to 0. 88 */ 89 @nogc 90 void collapse() pure nothrow { 91 this.radius = 0; 92 } 93 94 /** 95 * Checks if this Circle is empty (if it's collapsed) with SDL_RectEmpty. 96 */ 97 @nogc 98 bool isEmpty() const pure nothrow { 99 return this.radius == 0; 100 } 101 102 // /** 103 // * Checks whether this Circle contains the given coordinates. 104 // */ 105 // @nogc 106 // bool contains(const Vector2i vec) const pure nothrow { 107 // return this.contains(vec.x, vec.y); 108 // } 109 110 // /** 111 // * Checks whether this Circle contains the given coordinates. 112 // */ 113 // @nogc 114 // bool contains(int x, int y) const pure nothrow { 115 // // TODO 116 // } 117 118 /** 119 * opEquals: compares two rectangles on their coordinates and their size (but not explicit type). 120 */ 121 @nogc 122 bool opEquals(const Circle circle) const pure nothrow { 123 return this.x == circle.x && this.y == circle.y && this.radius == circle.radius; 124 } 125 126 /** 127 * Checks whether this Circle intersects with an other. 128 * If, and the parameter 'overlap' isn't null, 129 * the colliding circle is stored there. 130 */ 131 @nogc 132 bool intersects(const Circle circle, Circle* overlap = null) const { 133 immutable Vector2i center1 = getCenter(); 134 immutable Vector2i center2 = circle.getCenter(); 135 immutable int dx = center1.x - center2.x; 136 immutable int dy = center1.y - center2.y; 137 immutable float distance = sqrt(cast(float)dx * dx + dy * dy); 138 139 return distance < this.radius + circle.radius; 140 // TODO stored 141 } 142 143 /** 144 * Replace the current size. 145 */ 146 @nogc 147 void setRadius(uint radius) pure nothrow { 148 this.radius = radius; 149 } 150 151 /** 152 * Returns the current radius 153 */ 154 @nogc 155 uint getRadius() const pure nothrow { 156 return this.radius; 157 } 158 159 /** 160 * Increase current size. 161 */ 162 @nogc 163 void increase(int radius) pure nothrow { 164 this.radius += radius; 165 } 166 167 /** 168 * Set a new position with coordinates. 169 */ 170 @nogc 171 void setPosition(int x, int y) pure nothrow { 172 this.x = x; 173 this.y = y; 174 } 175 176 /** 177 * Set a new position with a vector. 178 */ 179 @nogc 180 void setPosition(const Vector2i position) pure nothrow { 181 this.setPosition(position.x, position.y); 182 } 183 184 /** 185 * Returns the current position as Vector2 186 */ 187 @nogc 188 Vector2i getPosition() const pure nothrow { 189 return Vector2i(this.x, this.y); 190 } 191 192 /** 193 * Move the object. 194 */ 195 @nogc 196 void move(const Vector2i vec) pure nothrow { 197 this.move(vec.x, vec.y); 198 } 199 200 /** 201 * Move the object. 202 */ 203 @nogc 204 void move(int x, int y) pure nothrow { 205 this.x += x; 206 this.y += y; 207 } 208 209 /** 210 * Returns the center position of this Circle 211 */ 212 @nogc 213 Vector2i getCenter() const pure nothrow { 214 return Vector2i(this.x + this.radius, this.y + this.radius); 215 } 216 }