-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmap.cpp
116 lines (99 loc) · 3.74 KB
/
map.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
#include "map.h"
Map::Map(cimg_library::CImg<unsigned char> *img, const unsigned char *color_dest, int acc_max) {
auto start = std::chrono::high_resolution_clock::now();
this->img = img;
this->acc_max = acc_max;
std::cout << "Création de la matrice en cours... ";
std::cout.flush();
// Initialise la map
for (int i = 0; i < img->width(); i++) {
for (int j = 0; j < img->height(); j++) {
Node *node = new Node(i, j);
map.push_back(node);
// Si c'est un pixel de destination
if (img->atXY(i, j, 0) == (int) color_dest[0] && img->atXY(i, j, 1) == (int) color_dest[1] &&
img->atXY(i, j, 2) == (int) color_dest[2]) {
node->isDestination = true;
this->destinationsNodes.push_back(node);
}
// Si c'est un mur
if (img->atXY(i, j, 0) == 0 && img->atXY(i, j, 1) == 0 && img->atXY(i, j, 2) == 0) {
node->isWall = true;
}
}
}
// Met les voisins de chaque noeuds
for (int i = 0; i < img->width(); i++) {
for (int j = 0; j < img->height(); j++) {
Node *node = getNode(i, j);
// Gauche
if (i > 0) {
node->neighbors->push_back(std::make_pair(getNode(i - 1, j), 1));
// Haut gauche
if (j > 0)
node->neighbors->push_back(std::make_pair(getNode(i - 1, j - 1), 1));
}
// Droite
if (i < img->width() - 1) {
node->neighbors->push_back(std::make_pair(getNode(i + 1, j), 1));
// Haut droite
if (j > 0)
node->neighbors->push_back(std::make_pair(getNode(i + 1, j - 1), 1));
}
// Haut
if (j > 0)
node->neighbors->push_back(std::make_pair(getNode(i, j - 1), 1));
// Bas
if (j < img->height() - 1) {
node->neighbors->push_back(std::make_pair(getNode(i, j + 1), 1));
// Bas gauche
if (i > 0)
node->neighbors->push_back(std::make_pair(getNode(i - 1, j + 1), 1));
}
// Diagonale bas droite
if (i < img->width() - 1 && j < img->height() - 1)
node->neighbors->push_back(std::make_pair(getNode(i + 1, j + 1), 1));
}
}
// Comme on a plusieurs destinations, on pourrait prendre la plus proche
// Sauf que s'il y a 17k points... Ca prend beaucoup de temps
// Donc on fait la moyenne des coordonnées des destinations
// Pour avoir à la fin un point central
double x = 0;
double y = 0;
for (auto &i: this->destinationsNodes) {
x += i->x;
y += i->y;
}
x /= (double) this->destinationsNodes.size();
y /= (double) this->destinationsNodes.size();
this->destination = getNode((int) x, (int) y);
auto stop = std::chrono::high_resolution_clock::now();
double duration = (double) duration_cast<std::chrono::microseconds>(stop - start).count();
duration /= 1000;
std::cout << "Terminé en " << duration << "ms." << std::endl;
}
Map::~Map() {
for (auto &i: map) {
delete i;
i = nullptr;
}
delete this->img;
this->img = nullptr;
}
void Map::print() {
for (int i = 0; i < img->width(); i++) {
for (int j = 0; j < img->height(); j++) {
Node *node = getNode(i, j);
if (node->isWall)
std::cout << "██";
else if (this->destination == node)
std::cout << "F ";
else if (node->isDestination)
std::cout << "D ";
else
std::cout << " ";
}
std::cout << std::endl;
}
}