]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.debug.graphical/src/org/simantics/debug/graphical/layout/LayoutAlgorithm.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.debug.graphical / src / org / simantics / debug / graphical / layout / LayoutAlgorithm.java
1 package org.simantics.debug.graphical.layout;
2
3 public class LayoutAlgorithm {
4
5     final double OPTIMAL_DISTANCE = 150.0;   
6     final double C = 0.1;
7     final double K = C / OPTIMAL_DISTANCE;
8     final double G = K;
9     final double Q = C * OPTIMAL_DISTANCE * OPTIMAL_DISTANCE;
10     final double TOLERANCE = 1e-3;
11     final int MAX_ITERATIONS = 10000;
12     final double MAX_MOVE2 = 40000.0;
13     
14     int size;
15     double[] posX;
16     double[] posY;
17     double[] forceX;
18     double[] forceY;
19     
20     int[][] neighbors;
21     
22     public LayoutAlgorithm(int[][] neighbors) {
23         this.size = neighbors.length;
24         this.neighbors = neighbors;
25         this.posX = new double[size];
26         this.posY = new double[size];
27         this.forceX = new double[size];
28         this.forceY = new double[size];
29     }
30     
31     public double[] getPosX() {
32         return posX;
33     }
34     
35     public double[] getPosY() {
36         return posY;
37     }
38     
39     private void computeForces() {
40         for(int i=0;i<size;++i) {
41             double x = posX[i];
42             double y = posY[i];
43             double fx = -G * x;
44             double fy = -G * y;
45             
46             for(int j=0;j<size;++j)
47                 if(j != i) {
48                     double dx = posX[j] - x;
49                     double dy = posY[j] - y;
50                     double l2 = dx*dx + dy*dy;
51                     /*double l = Math.sqrt(l2);
52                     double l3 = l*l2;*/
53                     fx -= Q * dx / l2;
54                     fy -= Q * dy / l2;
55                 }
56             
57             for(int j : neighbors[i]) {
58                 double dx = posX[j] - x;
59                 double dy = posY[j] - y;       
60                 double l2 = dx*dx + dy*dy;
61                 double l = Math.sqrt(l2);
62                 fx += K * l * dx;
63                 fy += K * l * dy;
64             }
65             
66             forceX[i] = fx;
67             forceY[i] = fy;
68         }
69     }
70     
71     private boolean converged() {
72         for(int i=0;i<size;++i) {
73             double fx = forceX[i];
74             double fy = forceY[i];
75             double f2 = fx*fx + fy*fy;
76             if(f2 > TOLERANCE)
77                 return false;
78         }
79         return true;
80     }
81     
82     private void moveAll() {
83         for(int i=0;i<size;++i) {
84             double fx = forceX[i];
85             double fy = forceY[i];
86             double f2 = fx*fx + fy*fy;
87             if(f2 > MAX_MOVE2) {
88                 double s = Math.sqrt(MAX_MOVE2 / f2);
89                 fx *= s;
90                 fy *= s;
91             }
92             posX[i] += fx;
93             posY[i] += fy;
94         }
95         computeForces();
96     }
97     
98     public void optimize() {
99         computeForces();
100         
101         for(int iter=0;iter<MAX_ITERATIONS;++iter) {
102             if(converged())
103                 break;
104             moveAll();
105         }
106     }
107 }