#pragma once // Layouts estaticos (no iterativos) para GraphData. Todos respetan NF_PINNED: // los nodos con ese flag conservan su posicion y velocidad. Las velocidades // del resto se ponen a cero al aplicar un layout. // // Para layouts iterativos (force-directed) ver graph_force_layout.h / // graph_force_layout_gpu.h. struct GraphData; namespace graph { // Cuadricula uniforme. spacing en world units. Coloca los nodos en columnas // de ceil(sqrt(N)) hasta filas. Centro del grafo en (0,0). void layout_grid (GraphData& graph, float spacing = 20.0f); // Circulo unico de radio `radius`. Centro en (0,0). void layout_circular (GraphData& graph, float radius = 100.0f); // Posiciones aleatorias en [-spread, spread] x [-spread, spread]. Usa rand(); // el caller puede llamar srand(seed) antes para reproducibilidad. void layout_random (GraphData& graph, float spread = 200.0f); // Layout radial tipo arbol: BFS desde `root_node`. Hop k -> circulo de radio // k * ring_spacing. Nodos del mismo hop se distribuyen uniformemente en su // circulo. Nodos no alcanzables (componentes desconectadas) van al ultimo hop+1. // Si `root_node` es invalido, usa el indice 0. void layout_radial (GraphData& graph, int root_node = 0, float ring_spacing = 80.0f); // Layout jerarquico estilo Sugiyama (heuristico). Asigna niveles via BFS // desde nodos sin in-edges (rank por longest-path). Dentro de cada nivel // ordena por baricentro respecto al nivel previo (greedy) para reducir // cruces de aristas. // // direction: // 0 = LR (left -> right, niveles en X creciente) // 1 = RL (right -> left) // 2 = TB (top -> bottom, niveles en Y creciente) // 3 = BT (bottom -> top) void layout_hierarchical(GraphData& graph, int direction = 0, float layer_spacing = 120.0f, float node_spacing = 60.0f); // No-op. Existe para que los callers puedan tratar "fixed" como un layout // mas en un switch sin casos especiales. NO toca posiciones, velocidades ni // flags. void layout_fixed (GraphData& graph); } // namespace graph