#include "Reader.h" #include #include #include #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& grids, const LongVector3& position); static std::tm end_of_time(); static bool earlier(const std::tm& lhs, const std::tm& rhs); std::vector Reader::read(Source& source) { std::vector 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((wreck.killmail.position.x - average.x) * SCALE), static_cast((wreck.killmail.position.y - average.y) * SCALE), static_cast((wreck.killmail.position.z - average.z) * SCALE), }; } grid.origin = average; } (void) start; (void) end; return grids; } Grid& find_grid_for(std::vector& 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::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; }