summaryrefslogtreecommitdiffhomepage
path: root/Reader.cpp
blob: f14b8374dd1fb9d40bdbbfcb684064050d8b81e3 (plain)
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
#include "Reader.h"

#include <ctime>
#include <vector>
#include <limits>

#include "Grid.h"
#include "LongVector3.h"
#include "Source.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);
static std::tm end_of_time();
static bool earlier(const std::tm& lhs, const std::tm& rhs);


std::vector<Grid>
Reader::read(Source& source)
{
    std::vector<Grid> grids;
    std::tm start = end_of_time();
    std::tm end = {};
    for (auto& km : source.killmails()) {
        if (earlier(km.time, start)) start = km.time;
        if (earlier(end, km.time)) end = km.time;
        auto& grid = find_grid_for(grids, km.position);
        grid.wrecks.push_back(Wreck{Vector3{0, 0, 0}, km});
    }
    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),
            };
        }
        grid.origin = average;
    }
    (void) start;
    (void) end;
    return grids;
}


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();
}


std::tm
end_of_time()
{
    std::tm time {};
    time.tm_sec = 60;
    time.tm_min = 59;
    time.tm_hour = 23;
    time.tm_mday = 31;
    time.tm_mon = 11;
    time.tm_year = std::numeric_limits<decltype(time.tm_year)>::max();
    return time;
}


bool
earlier(const std::tm& lhs, const std::tm& rhs)
{
    if (lhs.tm_year > rhs.tm_year) return false;
    if (lhs.tm_year < rhs.tm_year) return true;
    if (lhs.tm_mon > rhs.tm_mon) return false;
    if (lhs.tm_mon < rhs.tm_mon) return true;
    if (lhs.tm_mday > rhs.tm_mday) return false;
    if (lhs.tm_mday < rhs.tm_mday) return true;
    if (lhs.tm_hour > rhs.tm_hour) return false;
    if (lhs.tm_hour < rhs.tm_hour) return true;
    if (lhs.tm_min > rhs.tm_min) return false;
    if (lhs.tm_min < rhs.tm_min) return true;
    if (lhs.tm_sec > rhs.tm_sec) return false;
    if (lhs.tm_sec < rhs.tm_sec) return true;
    return false;
}