-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGJK.cpp
131 lines (95 loc) · 1.92 KB
/
GJK.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include "stdafx.h"
#include "GJK.h"
#include "Map.h"
#include "Game.h"
#include "Math.h"
GJK::GJK()
{
}
bool GJK::Check(Object* O1, Object* O2)
{
sf::Vector2f d(1, 0);
simplex.Add(support(O1, O2, d));
d.x = -d.x;
d.y = -d.y;
while (true)
{
simplex.Add(support(O1, O2, d));
if (Math::Dot(simplex.getLast(), d) < 0.0)
{
return false;
}
else
{
if (containsOrigin(d))
{
return true;
}
}
}
}
bool GJK::containsOrigin(sf::Vector2f& d)
{
sf::Vector2f A = simplex.getLast();
sf::Vector2f AO = -A;
if (simplex.points.size() == 3)
{
sf::Vector2f B = simplex.points[0];
sf::Vector2f C = simplex.points[1];
sf::Vector2f AB = B - A;
sf::Vector2f AC = C - A;
sf::Vector2f ABPerp = Math::tripleProduct(AC, AB, AB);
sf::Vector2f ACPerp = Math::tripleProduct(AB, AC, AC);
if ((Math::Dot(ABPerp, AO)) > 0)
{
simplex.Remove(1);
d = ABPerp;
d = Math::Normalise(d);
}
else
{
if ((Math::Dot(ACPerp, AO)) > 0)
{
simplex.Remove(0);
d = ACPerp;
d = Math::Normalise(d);
}
else
{
return true;
}
}
}
else
{
sf::Vector2f B = simplex.points[0];
sf::Vector2f AB = B - A;
sf::Vector2f ABPerp = Math::tripleProduct(AB, AO, AB);
d = ABPerp;
d = Math::Normalise(d);
}
return false;
}
sf::Vector2f GJK::support(Object* shape1, Object* shape2, sf::Vector2f d) {
std::vector<sf::Vector2f> points = shape1->GetPoints();
sf::Vector2f p1 = GetFarthest(points, d);
std::vector<sf::Vector2f> points2 = shape2->GetPoints();
sf::Vector2f p2 = GetFarthest(points2, -d);
sf::Vector2f p3 = p1-p2;
return p3;
}
sf::Vector2f GJK::GetFarthest(std::vector<sf::Vector2f> points, sf::Vector2f d)
{
sf::Vector2f farthest;
float farDistance = -9999999999999;
for (int i = 0; i < points.size(); i++)
{
float temp = Math::Dot(d, points[i]);
if (temp > farDistance)
{
farDistance = temp;
farthest = points[i];
}
}
return farthest;
}