package ProjectData.SapforData.Functions.UI.Graph; import javafx.util.Pair; import java.util.LinkedHashMap; import java.util.Vector; public class FunctionsGraphUIGreed extends FunctionsGraphUI { //веса вершин. protected LinkedHashMap weights = new LinkedHashMap<>(); //группы вершин по весам.в порядке убывания весов. protected LinkedHashMap> groups = new LinkedHashMap<>(); public FunctionsGraphUIGreed(GraphInfo graph_in) { super(graph_in); } @Override public void SetCoordinates() { //получить веса вершин. for (String name : graph.vertexMap.keySet()) { Vector edges = graph.vertexMap.get(name); //как минимум, вес вершины - это все исходящие из нее ребра. if (!weights.containsKey(name)) weights.put(name, edges.size()); else weights.replace(name, weights.get(name) + edges.size()); for (String dst : edges) { //есть ребро, значит уже вес 1 if (!weights.containsKey(dst)) weights.put(dst, 1); else weights.replace(dst, weights.get(dst) + 1); } } //сортировка по весу вершин. //1 определить максимальный вес. int max = 0; for (String name : weights.keySet()) if (weights.get(name) > max) max = weights.get(name); for (int i = max; i >= 0; --i) { Vector current_group = new Vector<>(); for (String name : weights.keySet()) { if (weights.get(name) == i) current_group.add(name); } if (current_group.size() > 0) { groups.put(i, current_group); } } //linked hash map - сохраняет порядок. поэтому они уже по убыванию. //теперь координаты. берем самую тыжелую группу, правильный многоугольник по центру //поток следующая, вокруг первого, и т д. int R = 150; int i = 0; double x_offet = 0; double y_ofset = 0; double rot = 0.0; //чтобы не было линеечки с каждой группой вращаем многоугольники. for (int w : groups.keySet()) { //первая вершина - особый случай. если она одна - ее в центр и надо if ((i == 0) && (groups.get(w).size() == 1)) { graph.vertexCoordinates.put(groups.get(w).get(0), new Pair<>(0.0, 0.0)); } else { double phi0 = rot; double phi = 2 * Math.PI / groups.get(w).size(); for (String name : groups.get(w)) { double x = R * Math.cos(phi0); double y = R * Math.sin(phi0); if (x < x_offet) x_offet = x; if (y < y_ofset) y_ofset = y; //todo добавить в рассчет прямоугольник и самой вершины. graph.vertexCoordinates.put(name, new Pair<>(x, y)); phi0 += phi; } R += 100; } ++i; rot += 10; if (rot > 360.0) rot = 0.0; } x_offet *= -1; y_ofset *= -1; //теперь надо применить смещение. смещение. чтобы не было отрицательных координат. for (String name : graph.vertexCoordinates.keySet()) { Pair old = graph.vertexCoordinates.get(name); graph.vertexCoordinates.replace(name, new Pair<>(old.getKey() + x_offet + 50, old.getValue() + y_ofset + 50)); } } }