Files
VisualSapfor/src/ProjectData/SapforData/Functions/UI/Graph/FunctionsGraphUIGreed.java

81 lines
4.0 KiB
Java
Raw Normal View History

2023-09-17 22:13:42 +03:00
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<String, Integer> weights = new LinkedHashMap<>();
//группы вершин по весам.в порядке убывания весов.
protected LinkedHashMap<Integer, Vector<String>> groups = new LinkedHashMap<>();
public FunctionsGraphUIGreed(GraphInfo graph_in) {
super(graph_in);
}
@Override
public void SetCoordinates() {
//получить веса вершин.
for (String name : graph.vertexMap.keySet()) {
Vector<String> 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<String> 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<Double, Double> old = graph.vertexCoordinates.get(name);
graph.vertexCoordinates.replace(name, new Pair<>(old.getKey() + x_offet + 50, old.getValue() + y_ofset + 50));
}
}
}