GraphLayout { public void updateLocation(Map<Location, Integer> locationsAndWeights, Location location, double epsilon) { if (locationsAndWeights.size() <= 1) { return; } computeCentroid(locationsAndWeights.keySet(), location); Location maxLocation = null; int maxWeight = 0; for (Map.Entry<Location, Integer> entry : locationsAndWeights.entrySet()) { int weight = entry.getValue(); if (weight > maxWeight) { maxWeight = weight; maxLocation = entry.getKey(); } } for (int i = 0; i < _maxIterations; ++i) { Map<Location, Double> distancesByLocation = new HashMap<Location, Double>(); double maxDistance = 0; for (Map.Entry<Location, Integer> entry : locationsAndWeights.entrySet()) { Location otherLocation = entry.getKey(); double dx = otherLocation.x - location.x; double dy = otherLocation.y - location.y; double d = Math.sqrt(dx * dx + dy * dy); distancesByLocation.put(otherLocation, d); maxDistance = Math.max(d, maxDistance); } double referenceDistance = distancesByLocation.get(maxLocation); double vx = 0; double vy = 0; for (Map.Entry<Location, Double> entry : distancesByLocation.entrySet()) { Location otherLocation = entry.getKey(); double distance = distancesByLocation.get(otherLocation); double ratio = (double) locationsAndWeights.get(otherLocation) / maxWeight; double delta = distance - ratio * referenceDistance; double dx = (otherLocation.x - location.x) * delta / distance; double dy = (otherLocation.y - location.y) * delta / distance; vx += dx; vy += dy; } vx /= 2; vy /= 2; double vDistance = Math.sqrt(vx * vx + vy * vy); if (vDistance / maxDistance < epsilon / 2) { return; } location.x += vx; location.y += vy; } _log.warn("max number of iterations reached"); }  void updateLocation(Map<Location, Integer> locationsAndWeights,
      Location location, double epsilon); void computeCentroid(Set<Location> locations, Location location);  }
@Test public void testA() { Location a = new Location(); a.x = 0; a.y = 0; Location b = new Location(); b.x = 1; b.y = 0; Map<Location, Integer> weights = new HashMap<Location, Integer>(); weights.put(a, 1); weights.put(b, 3); Location c = new Location(); c.x = 0.5; c.y = 0; layout_.updateLocation(weights, c, 0.001); assertEquals(0.25, c.x, 0.001); assertEquals(0.00, c.y, 0.001); }
@Test public void testB() { Location a = new Location(); a.x = 1; a.y = 1; Location b = new Location(); b.x = 9; b.y = 5; Map<Location, Integer> weights = new HashMap<Location, Integer>(); weights.put(a, 1); weights.put(b, 3); Location c = new Location(); c.x = 1.2; c.y = 1.2; layout_.updateLocation(weights, c, 0.001); assertEquals(3.0, c.x, 0.01); assertEquals(2.0, c.y, 0.01 ); }