147 lines
4.6 KiB
C++
147 lines
4.6 KiB
C++
#include "calc.hpp"
|
|
#include <cmath>
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
#include <sstream>
|
|
#include <boost/multiprecision/cpp_dec_float.hpp>
|
|
|
|
std::vector<std::vector<Decimal>> calculate_distances(const std::vector<Position>& positions) {
|
|
int N = positions.size();
|
|
std::vector<std::vector<Decimal>> dists(N, std::vector<Decimal>(N, Decimal(0)));
|
|
|
|
for (int i = 0; i < N; ++i) {
|
|
for (int j = i + 1; j < N; ++j) {
|
|
Decimal sum = Decimal(0);
|
|
for (int k = 0; k < 3; ++k) {
|
|
Decimal diff = positions[i][k] - positions[j][k];
|
|
sum += diff * diff;
|
|
}
|
|
Decimal d = std::sqrt(sum);
|
|
dists[i][j] = d;
|
|
dists[j][i] = d;
|
|
}
|
|
}
|
|
return dists;
|
|
}
|
|
|
|
std::string format_sig_figs(Decimal value, int sig_figs) {
|
|
if (value == 0) {
|
|
return "0";
|
|
}
|
|
|
|
std::stringstream ss;
|
|
ss << std::scientific << std::setprecision(sig_figs - 1) << value;
|
|
return ss.str();
|
|
}
|
|
|
|
void print_progress_bar(int iteration, int total, std::chrono::time_point<std::chrono::steady_clock> start_time, int length, Decimal step_size) {
|
|
float percent = (float)iteration / total * 100;
|
|
int filled_length = length * iteration / total;
|
|
|
|
std::string bar;
|
|
bar.reserve(length + 1);
|
|
bar += '[';
|
|
bar.append(filled_length, '#');
|
|
bar.append(length - filled_length, '-');
|
|
bar += ']';
|
|
|
|
auto now = std::chrono::steady_clock::now();
|
|
auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(now - start_time).count();
|
|
double steps_per_second = elapsed > 0 ? real_time(Decimal(iteration) * step_size) / elapsed : 0;
|
|
|
|
// Determine appropriate time unit
|
|
std::string time_unit;
|
|
if (steps_per_second >= 3600) {
|
|
time_unit = "hour/s";
|
|
steps_per_second /= 3600;
|
|
} else if (steps_per_second >= 60) {
|
|
time_unit = "min/s";
|
|
steps_per_second /= 60;
|
|
} else {
|
|
time_unit = "s/s";
|
|
}
|
|
|
|
// Clear the current line and move cursor to start
|
|
std::cout << "\r\033[K";
|
|
|
|
// Print the progress bar
|
|
std::cout << bar << " " << std::fixed << std::setprecision(2)
|
|
<< percent << "% " << std::setprecision(1) << steps_per_second << " " << time_unit << std::flush;
|
|
}
|
|
|
|
#ifdef NCURSES_ENABLED
|
|
void plot_points_terminal(const std::vector<Position>& vectors, WINDOW* stdscr,
|
|
Decimal scale, int grid_width, int grid_height) {
|
|
if (vectors.empty()) {
|
|
mvwaddstr(stdscr, 0, 0, "No vectors provided.");
|
|
wrefresh(stdscr);
|
|
return;
|
|
}
|
|
|
|
// Scale and round vectors
|
|
std::vector<std::pair<int, int>> scaled_vectors;
|
|
for (const auto& vec : vectors) {
|
|
scaled_vectors.emplace_back(
|
|
std::round(vec[0] / scale),
|
|
std::round(vec[1] / scale)
|
|
);
|
|
}
|
|
|
|
// Find bounds
|
|
int min_x = scaled_vectors[0].first;
|
|
int max_x = min_x;
|
|
int min_y = scaled_vectors[0].second;
|
|
int max_y = min_y;
|
|
|
|
for (const auto& vec : scaled_vectors) {
|
|
min_x = std::min(min_x, vec.first);
|
|
max_x = std::max(max_x, vec.first);
|
|
min_y = std::min(min_y, vec.second);
|
|
max_y = std::max(max_y, vec.second);
|
|
}
|
|
|
|
// Center offsets
|
|
int center_x = (grid_width / 2) - min_x;
|
|
int center_y = (grid_height / 2) - min_y;
|
|
|
|
// Adjust coordinates
|
|
std::vector<std::pair<int, int>> adjusted_vectors;
|
|
for (const auto& vec : scaled_vectors) {
|
|
adjusted_vectors.emplace_back(
|
|
vec.first + center_x,
|
|
vec.second + center_y
|
|
);
|
|
}
|
|
|
|
// Get terminal bounds
|
|
int max_terminal_y, max_terminal_x;
|
|
getmaxyx(stdscr, max_terminal_y, max_terminal_x);
|
|
max_x = std::min(grid_width, max_terminal_x - 5);
|
|
max_y = std::min(grid_height, max_terminal_y - 5);
|
|
|
|
// Draw grid
|
|
for (int i = grid_height; i >= 0; --i) {
|
|
std::string row = std::to_string(i - center_y) + " | ";
|
|
for (int j = 0; j <= grid_width; ++j) {
|
|
bool has_point = false;
|
|
for (const auto& vec : adjusted_vectors) {
|
|
if (vec.first == j && vec.second == i) {
|
|
has_point = true;
|
|
break;
|
|
}
|
|
}
|
|
row += has_point ? "● " : ". ";
|
|
}
|
|
mvwaddstr(stdscr, max_y - i, 0, row.substr(0, max_terminal_x - 1).c_str());
|
|
}
|
|
|
|
// Print X-axis labels
|
|
std::string x_labels = " ";
|
|
for (int j = 0; j <= max_x; ++j) {
|
|
x_labels += std::to_string(j - center_x) + " ";
|
|
}
|
|
mvwaddstr(stdscr, max_y + 1, 0, x_labels.substr(0, max_terminal_x - 1).c_str());
|
|
|
|
wrefresh(stdscr);
|
|
}
|
|
#endif |