Merge "Bug 2347: DOMConcurrentDataCommitCoordinator uses wrong phase name"
[controller.git] / third-party / net.sf.jung2 / src / main / java / edu / uci / ics / jung / algorithms / layout / SpringLayout2.java
1 /*
2  * Copyright (c) 2003, the JUNG Project and the Regents of the University of
3  * California All rights reserved.
4  * 
5  * This software is open-source under the BSD license; see either "license.txt"
6  * or http://jung.sourceforge.net/license.txt for a description.
7  */
8 package edu.uci.ics.jung.algorithms.layout;
9
10 import java.awt.Dimension;
11 import java.awt.geom.Point2D;
12 import java.util.ConcurrentModificationException;
13
14 import org.apache.commons.collections15.Transformer;
15
16 import edu.uci.ics.jung.graph.Graph;
17
18 /**
19  * The SpringLayout package represents a visualization of a set of nodes. The
20  * SpringLayout, which is initialized with a Graph, assigns X/Y locations to
21  * each node. When called <code>relax()</code>, the SpringLayout moves the
22  * visualization forward one step.
23  * 
24  * 
25  * 
26  * @author Danyel Fisher
27  * @author Joshua O'Madadhain
28  */
29 public class SpringLayout2<V, E> extends SpringLayout<V,E> 
30 {
31     protected int currentIteration;
32     protected int averageCounter;
33     protected int loopCountMax = 4;
34     protected boolean done;
35     
36     protected Point2D averageDelta = new Point2D.Double();
37     
38     /**
39      * Constructor for a SpringLayout for a raw graph with associated
40      * dimension--the input knows how big the graph is. Defaults to the unit
41      * length function.
42      */
43     @SuppressWarnings("unchecked")
44     public SpringLayout2(Graph<V,E> g) {
45         super(g);
46     }
47
48     /**
49      * Constructor for a SpringLayout for a raw graph with associated component.
50      *
51      * @param g the {@code Graph} to lay out
52      * @param length_function provides a length for each edge
53      */
54     public SpringLayout2(Graph<V,E> g, Transformer<E, Integer> length_function)
55     {
56         super(g, length_function);
57     }
58
59     /**
60      * Relaxation step. Moves all nodes a smidge.
61      */
62     @Override
63     public void step() {
64         super.step();
65         currentIteration++;
66         testAverageDeltas();
67     }
68     
69     private void testAverageDeltas() {
70         double dx = this.averageDelta.getX();
71         double dy = this.averageDelta.getY();
72         if(Math.abs(dx) < .001 && Math.abs(dy) < .001) {
73                 done = true;
74                 System.err.println("done, dx="+dx+", dy="+dy);
75         }
76         if(currentIteration > loopCountMax) {
77                 this.averageDelta.setLocation(0,0);
78                 averageCounter = 0;
79                 currentIteration = 0;
80         }
81     }
82
83     @Override
84     protected void moveNodes() {
85         synchronized (getSize()) {
86             try {
87                 for (V v : getGraph().getVertices()) {
88                     if (isLocked(v)) continue;
89                     SpringVertexData vd = springVertexData.get(v);
90                     if(vd == null) continue;
91                     Point2D xyd = transform(v);
92                     
93                     vd.dx += vd.repulsiondx + vd.edgedx;
94                     vd.dy += vd.repulsiondy + vd.edgedy;
95                     
96 //                    int currentCount = currentIteration % this.loopCountMax;
97 //                    System.err.println(averageCounter+" --- vd.dx="+vd.dx+", vd.dy="+vd.dy);
98 //                    System.err.println("averageDelta was "+averageDelta);
99
100                     averageDelta.setLocation(
101                                 ((averageDelta.getX() * averageCounter) + vd.dx) / (averageCounter+1),
102                                 ((averageDelta.getY() * averageCounter) + vd.dy) / (averageCounter+1)
103                                 );
104 //                    System.err.println("averageDelta now "+averageDelta);
105 //                    System.err.println();
106                     averageCounter++;
107                     
108                     // keeps nodes from moving any faster than 5 per time unit
109                     xyd.setLocation(xyd.getX()+Math.max(-5, Math.min(5, vd.dx)),
110                                 xyd.getY()+Math.max(-5, Math.min(5, vd.dy)));
111                     
112                     Dimension d = getSize();
113                     int width = d.width;
114                     int height = d.height;
115                     
116                     if (xyd.getX() < 0) {
117                         xyd.setLocation(0, xyd.getY());//                     setX(0);
118                     } else if (xyd.getX() > width) {
119                         xyd.setLocation(width, xyd.getY());             //setX(width);
120                     }
121                     if (xyd.getY() < 0) {
122                         xyd.setLocation(xyd.getX(),0);//setY(0);
123                     } else if (xyd.getY() > height) {
124                         xyd.setLocation(xyd.getX(), height);      //setY(height);
125                     }
126                     
127                 }
128             } catch(ConcurrentModificationException cme) {
129                 moveNodes();
130             }
131         }
132     }
133
134     @Override
135     public boolean done() {
136         return done;
137     }
138
139 }