#include "calc.hpp" #include #include #include #include #include std::vector> calculate_distances(const std::vector& positions) { int N = positions.size(); std::vector> dists(N, std::vector(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 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(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& 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> 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> 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