]> git.localhorst.tv Git - sdl-test7.git/blob - src/geometry/Circle.cpp
imported current version
[sdl-test7.git] / src / geometry / Circle.cpp
1 /*
2  * Circle.cpp
3  *
4  *  Created on: Apr 20, 2012
5  *      Author: holy
6  */
7
8 #include "Circle.h"
9
10 #include "AABB.h"
11 #include "FakeLens.h"
12 #include "../game/Entity.h"
13
14
15 namespace geometry {
16
17 bool Circle::Overlaps(const Shape &other, Vector &normal) const {
18         if (other.Overlaps(*this, normal)) {
19                 normal *= -1;
20                 return true;
21         } else {
22                 return false;
23         }
24 }
25
26 bool Circle::Overlaps(const AABB &other, Vector &normal) const {
27         // fast checks for far away shapes
28         if (Bottom() <= other.Top()) return false;
29         if (other.Bottom() <= Top()) return false;
30         if (Right() <= other.Left()) return false;
31         if (other.Right() <= Left()) return false;
32
33         int xZone(
34                         X() < other.Left() ? 0 : (
35                         other.Right() < X() ? 2 : 1));
36         int yZone(
37                                 Y() < other.Top() ? 0 : (
38                                 other.Bottom() < Y() ? 2 : 1));
39         int zone(xZone + 3*yZone);
40
41         if (zone == 4) {
42                 normal = (Center() - other.Center()).Unit();
43                 return true;
44         }
45
46         if (zone % 2) {
47                 if (xZone == 1) { // vertical
48                         if (Bottom() < other.Top()) return false;
49                         if (other.Bottom() < Top()) return false;
50
51                         if (Bottom() < other.Bottom()) {
52                                 normal = Vector(0, -1);
53                         } else {
54                                 normal = Vector(0, 1);
55                         }
56
57                         return true;
58                 } else {
59                         if (Right() < other.Left()) return false;
60                         if (other.Right() < Left()) return false;
61
62                         if (Left() < other.Left()) {
63                                 normal = Vector(-1, 0);
64                         } else {
65                                 normal = Vector(1, 0);
66                         }
67
68                         return true;
69                 }
70         } else {
71                 Vector near(
72                                 yZone ? other.Right() : other.Left(),
73                                 xZone ? other.Bottom() : other.Top());
74                 Vector distance(position - near);
75                 Sint32 distanceSquared(distance.LengthSquared());
76                 if (distanceSquared < (Radius() * Radius())) {
77                         normal = distance.Unit();
78                         return true;
79                 } else {
80                         return false;
81                 }
82         }
83 }
84
85 bool Circle::Overlaps(const Circle &other, Vector &normal) const {
86         Vector delta(position - other.position);
87         Sint32 distanceSquared(delta.LengthSquared()), minDistance(Radius() + other.Radius());
88         if (distanceSquared < (minDistance * minDistance)) {
89                 normal = delta.Unify();
90                 return true;
91         } else {
92                 return false;
93         }
94 }
95
96 bool Circle::Overlaps(const FakeLens &other, Vector &normal) const {
97         if (other.Overlaps(*this, normal)) {
98                 normal *= -1;
99                 return true;
100         } else {
101                 return false;
102         }
103 }
104
105 std::ostream &Circle::Write(std::ostream &out) const {
106         return out << "Circle(" << Radius() << '+' << Top() << '+' << Left() << ')';
107 }
108
109 }