]> git.localhorst.tv Git - sdl-test8.git/blobdiff - src/shape/Circle.cpp
added collision engine, more or less stole gameplay from sdl-test7
[sdl-test8.git] / src / shape / Circle.cpp
diff --git a/src/shape/Circle.cpp b/src/shape/Circle.cpp
new file mode 100644 (file)
index 0000000..3549db9
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Circle.cpp
+ *
+ *  Created on: Apr 29, 2012
+ *      Author: holy
+ */
+
+#include "Circle.h"
+
+#include "AABB.h"
+
+namespace shape {
+
+void Circle::Translate(const Vector &delta) {
+       center += delta;
+}
+
+void Circle::Rotate(Scalar delta) {
+
+}
+
+
+bool Circle::CheckCollision(const Shape &other, Ray &na) const {
+       if (other.CheckCollision(*this, na)) {
+               na.Direction() *= -1;
+               return true;
+       } else {
+               return false;
+       }
+}
+
+bool Circle::CheckCollision(const AABB &other, Ray &na) const {
+       int xZone(
+                       center.X() < other.Left() ? 0 : (
+                       other.Right() < center.X() ? 2 : 1));
+       int yZone(
+                               center.Y() < other.Top() ? 0 : (
+                               other.Bottom() < center.Y() ? 2 : 1));
+       int zone(xZone + 3 * yZone);
+
+       if (zone == 4) {
+               na.Origin() = center;
+               na.Direction() = (center - other.Center()).Unit();
+               return true;
+       }
+
+       if (zone % 2) {
+               if (xZone == 1) { // vertical
+                       if (Bottom() < other.Top()) return false;
+                       if (other.Bottom() < Top()) return false;
+
+                       if (Bottom() < other.Bottom()) {
+                               na.Origin() = Vector(center.X(), Bottom());
+                               na.Direction() = Vector(0, -1);
+                       } else {
+                               na.Origin() = Vector(center.X(), Top());
+                               na.Direction() = Vector(0, 1);
+                       }
+
+                       return true;
+               } else {
+                       if (Right() < other.Left()) return false;
+                       if (other.Right() < Left()) return false;
+
+                       if (Left() < other.Left()) {
+                               na.Origin() = Vector(Left(), center.Y());
+                               na.Direction() = Vector(-1, 0);
+                       } else {
+                               na.Origin() = Vector(Right(), center.Y());
+                               na.Direction() = Vector(1, 0);
+                       }
+
+                       return true;
+               }
+       } else {
+               Vector near(
+                               yZone ? other.Right() : other.Left(),
+                               xZone ? other.Bottom() : other.Top());
+               Vector distance(Center() - near);
+               Scalar distanceSquared(distance.LengthSquared());
+               if (distanceSquared < (Radius() * Radius())) {
+                       na.Origin() = near;
+                       na.Direction() = distance.Unit();
+                       return true;
+               } else {
+                       return false;
+               }
+       }
+}
+
+bool Circle::CheckCollision(const Circle &other, Ray &na) const {
+       const Vector distance(center - other.center);
+       const Scalar distanceSquared(distance.LengthSquared());
+       const Scalar radii(radius + other.radius);
+
+       if (distanceSquared < (radii * radii)) {
+               na.Direction() = distance.Unit();
+               na.Origin() = center + (na.Direction() * radius);
+               return true;
+       } else {
+               return false;
+       }
+}
+
+
+std::ostream &Circle::Write(std::ostream &out) const {
+       return out << "Circle(" << Radius() << ", " << Center() << ')';
+}
+
+}