All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.googlecode.blaisemath.graph.mod.layout.SpringLayoutState Maven / Gradle / Ivy

/**
 * SpringLayoutState.java
 * Created Jan 16, 2016
 */
package com.googlecode.blaisemath.graph.mod.layout;

/*
 * #%L
 * BlaiseGraphTheory (v3)
 * --
 * Copyright (C) 2009 - 2016 Elisha Peterson
 * --
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */


import com.google.common.collect.Lists;
import com.googlecode.blaisemath.graph.IterativeGraphLayoutState;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.concurrent.GuardedBy;
import javax.annotation.concurrent.ThreadSafe;

/**
 * 

* State object for spring layout. This tracks node locations and velocities, * and divides node space up into regions to allow for more efficient * layout calculations. *

*

* This class may be safely modified by multiple threads simultaneously. *

* @param graph node type * @author elisha */ @ThreadSafe public final class SpringLayoutState extends IterativeGraphLayoutState { // private static final Logger LOG = Logger.getLogger(SpringLayoutState.class.getName()); /** # of regions away from origin in x and y directions. Region size is determined by the maximum repel distance. */ private static final int REGION_N = 5; // /** Regions used for localizing computation */ @GuardedBy("this") LayoutRegion[][] regions; /** Points that are not in a region */ @GuardedBy("this") LayoutRegion oRegion; /** List of all regions */ @GuardedBy("this") List> allRegions; // Point2D.Double getLoc(C io) { return loc.get(io); } void putLoc(C io, Point2D.Double pt) { loc.put(io, pt); } Point2D.Double getVel(C io) { return vel.get(io); } void putVel(C io, Point2D.Double pt) { vel.put(io, pt); } // // /** Updates the alignment of points to region */ void updateRegions(double regionSz) { if (regions == null) { initRegions(regionSz); } for (LayoutRegion r : allRegions) { r.clear(); } for (Map.Entry en : loc.entrySet()) { LayoutRegion r = regionByLoc(en.getValue(), regionSz); if (r != null) { r.put(en.getKey(), en.getValue()); } else { LOG.log(Level.WARNING, "Point not in any region: {0}", en); } } } /** Return region for specified point */ private LayoutRegion regionByLoc(Point2D.Double p, double regionSz) { int ix = (int) ((p.x + REGION_N * regionSz) / regionSz); int iy = (int) ((p.y + REGION_N * regionSz) / regionSz); if (ix < 0 || ix > 2 * REGION_N || iy < 0 || iy > 2 * REGION_N) { return oRegion; } return regions[ix][iy]; } /** Initializes regions */ private void initRegions(double maxRepelDist) { regions = new LayoutRegion[2 * REGION_N + 1][2 * REGION_N + 1]; allRegions = Lists.newArrayList(); for (int ix = -REGION_N; ix <= REGION_N; ix++) { for (int iy = -REGION_N; iy <= REGION_N; iy++) { Rectangle2D.Double rect = new Rectangle2D.Double(ix * maxRepelDist, iy * maxRepelDist, maxRepelDist, maxRepelDist); LayoutRegion region = new LayoutRegion(rect); regions[ix + REGION_N][iy + REGION_N] = region; allRegions.add(region); } } // set up adjacencies for (int ix = -REGION_N; ix <= REGION_N; ix++) { for (int iy = -REGION_N; iy <= REGION_N; iy++) { for (int ix2 = Math.max(ix - 1, -REGION_N); ix2 <= Math.min(ix + 1, REGION_N); ix2++) { for (int iy2 = Math.max(iy - 1, -REGION_N); iy2 <= Math.min(iy + 1, REGION_N); iy2++) { regions[ix + REGION_N][iy + REGION_N].addAdjacentRegion(regions[ix2 + REGION_N][iy2 + REGION_N]); } } } } // set up adjacencies with outer region oRegion = new LayoutRegion(null); allRegions.add(oRegion); oRegion.addAdjacentRegion(oRegion); for (int ix = -REGION_N; ix <= REGION_N; ix++) { LayoutRegion min = regions[ix + REGION_N][0]; LayoutRegion max = regions[ix + REGION_N][2 * REGION_N]; min.addAdjacentRegion(oRegion); max.addAdjacentRegion(oRegion); oRegion.addAdjacentRegion(min); oRegion.addAdjacentRegion(max); } for (int iy = -REGION_N + 1; iy <= REGION_N - 1; iy++) { LayoutRegion min = regions[0][iy + REGION_N]; LayoutRegion max = regions[2 * REGION_N][iy + REGION_N]; min.addAdjacentRegion(oRegion); max.addAdjacentRegion(oRegion); oRegion.addAdjacentRegion(min); oRegion.addAdjacentRegion(max); } } // }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy