01: package prefuse.util.force;
02:
03: /**
04: * Force function that computes the force acting on ForceItems due to a
05: * given Spring.
06: *
07: * @author <a href="http://jheer.org">jeffrey heer</a>
08: */
09: public class SpringForce extends AbstractForce {
10:
11: private static String[] pnames = new String[] {
12: "SpringCoefficient", "DefaultSpringLength" };
13:
14: public static final float DEFAULT_SPRING_COEFF = 1E-4f;
15: public static final float DEFAULT_MAX_SPRING_COEFF = 1E-3f;
16: public static final float DEFAULT_MIN_SPRING_COEFF = 1E-5f;
17: public static final float DEFAULT_SPRING_LENGTH = 50;
18: public static final float DEFAULT_MIN_SPRING_LENGTH = 0;
19: public static final float DEFAULT_MAX_SPRING_LENGTH = 200;
20: public static final int SPRING_COEFF = 0;
21: public static final int SPRING_LENGTH = 1;
22:
23: /**
24: * Create a new SpringForce.
25: * @param springCoeff the default spring co-efficient to use. This will
26: * be used if the spring's own co-efficient is less than zero.
27: * @param defaultLength the default spring length to use. This will
28: * be used if the spring's own length is less than zero.
29: */
30: public SpringForce(float springCoeff, float defaultLength) {
31: params = new float[] { springCoeff, defaultLength };
32: minValues = new float[] { DEFAULT_MIN_SPRING_COEFF,
33: DEFAULT_MIN_SPRING_LENGTH };
34: maxValues = new float[] { DEFAULT_MAX_SPRING_COEFF,
35: DEFAULT_MAX_SPRING_LENGTH };
36: }
37:
38: /**
39: * Constructs a new SpringForce instance with default parameters.
40: */
41: public SpringForce() {
42: this (DEFAULT_SPRING_COEFF, DEFAULT_SPRING_LENGTH);
43: }
44:
45: /**
46: * Returns true.
47: * @see prefuse.util.force.Force#isSpringForce()
48: */
49: public boolean isSpringForce() {
50: return true;
51: }
52:
53: /**
54: * @see prefuse.util.force.AbstractForce#getParameterNames()
55: */
56: protected String[] getParameterNames() {
57: return pnames;
58: }
59:
60: /**
61: * Calculates the force vector acting on the items due to the given spring.
62: * @param s the Spring for which to compute the force
63: * @see prefuse.util.force.Force#getForce(prefuse.util.force.Spring)
64: */
65: public void getForce(Spring s) {
66: ForceItem item1 = s.item1;
67: ForceItem item2 = s.item2;
68: float length = (s.length < 0 ? params[SPRING_LENGTH] : s.length);
69: float x1 = item1.location[0], y1 = item1.location[1];
70: float x2 = item2.location[0], y2 = item2.location[1];
71: float dx = x2 - x1, dy = y2 - y1;
72: float r = (float) Math.sqrt(dx * dx + dy * dy);
73: if (r == 0.0) {
74: dx = ((float) Math.random() - 0.5f) / 50.0f;
75: dy = ((float) Math.random() - 0.5f) / 50.0f;
76: r = (float) Math.sqrt(dx * dx + dy * dy);
77: }
78: float d = r - length;
79: float coeff = (s.coeff < 0 ? params[SPRING_COEFF] : s.coeff)
80: * d / r;
81: item1.force[0] += coeff * dx;
82: item1.force[1] += coeff * dy;
83: item2.force[0] += -coeff * dx;
84: item2.force[1] += -coeff * dy;
85: }
86:
87: } // end of class SpringForce
|