#include "layout.hpp" #include "algebra.hpp" #include #include namespace nodesoup { using std::vector; void circle(const adj_list_t& g, vector& positions) { const double pi = 3.14159265358979323846; double angle = 2.0 * pi / g.size(); for (vertex_id_t v_id = 0; v_id < g.size(); v_id++) { positions[v_id].x = cos(v_id * angle); positions[v_id].y = sin(v_id * angle); } } void center_and_scale(const adj_list_t& g, unsigned int width, unsigned int height, vector& positions) { // find current dimensions double x_min = std::numeric_limits::max(); double x_max = std::numeric_limits::lowest(); double y_min = std::numeric_limits::max(); double y_max = std::numeric_limits::lowest(); for (vertex_id_t v_id = 0; v_id < g.size(); v_id++) { if (positions[v_id].x < x_min) x_min = positions[v_id].x; if (positions[v_id].x > x_max) x_max = positions[v_id].x; if (positions[v_id].y < y_min) y_min = positions[v_id].y; if (positions[v_id].y > y_max) y_max = positions[v_id].y; } double cur_width = x_max - x_min; double cur_height = y_max - y_min; // compute scale factor (0.9: keep some margin) double x_scale = (cur_width > 0) ? width / cur_width : width; double y_scale = (cur_height > 0) ? height / cur_height : height; Vector2D scale = { x_scale, y_scale }; // compute offset and apply it to every position Vector2D center = { x_max + x_min, y_max + y_min }; Vector2D offset = (center / 2.0) * scale; double shiftMinX = std::numeric_limits::max(); double shiftMinY = std::numeric_limits::max(); for (vertex_id_t v_id = 0; v_id < g.size(); v_id++) { positions[v_id] = (Point2D)((Vector2D)positions[v_id] * scale - offset); shiftMinX = std::min(shiftMinX, positions[v_id].x); shiftMinY = std::min(shiftMinY, positions[v_id].y); } shiftMinX = abs(shiftMinX) + 50; shiftMinY = abs(shiftMinY) + 50; for (auto& pos : positions) { pos.x += shiftMinX; pos.y += shiftMinY; } } }