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
|
#include "Reader.h"
#include <ctime>
#include <limits>
#include <tuple>
#include <vector>
#include "Grid.h"
#include "LongVector3.h"
#include "Source.h"
#include "Timeline.h"
#include "Utils.h"
#include "Wreck.h"
static constexpr long double SCALE {.0001};
static constexpr long double EXTENT {1000 * 50000};
static Grid& find_grid_for(std::vector<Grid>& grids, const LongVector3& position);
std::tuple<std::vector<Grid>, Timeline>
Reader::read(Source& source)
{
std::vector<Grid> grids;
std::time_t start {std::numeric_limits<std::time_t>::max()};
std::time_t end {0};
for (auto& km : source.killmails()) {
if (km.time < start) start = km.time;
if (end < km.time) end = km.time;
auto& grid = find_grid_for(grids, km.position);
grid.wrecks.push_back(Wreck{Vector3{0, 0, 0}, km, 0});
}
for (auto& grid : grids) {
LongVector3 average {0, 0, 0};
for (const auto& wreck : grid.wrecks) {
average.x += wreck.killmail.position.x;
average.y += wreck.killmail.position.y;
average.z += wreck.killmail.position.z;
}
const auto killmails = grid.wrecks.size();
average.x /= killmails;
average.y /= killmails;
average.z /= killmails;
for (auto& wreck : grid.wrecks) {
wreck.position = {
static_cast<float>((wreck.killmail.position.x - average.x) * SCALE),
static_cast<float>((wreck.killmail.position.y - average.y) * SCALE),
static_cast<float>((wreck.killmail.position.z - average.z) * SCALE),
};
wreck.time = static_cast<double>(wreck.killmail.time - start);
}
grid.origin = average;
}
Timeline timeline(start, end);
return {grids, timeline};
}
Grid&
find_grid_for(std::vector<Grid>& grids, const LongVector3& position)
{
for (auto& grid : grids)
for (auto& wreck : grid.wrecks)
if (dist(position, wreck.killmail.position) < EXTENT)
return grid;
grids.push_back(Grid{});
return grids.back();
}
|