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

edu.uci.ics.jung.algorithms.layout.RadiusGraphElementAccessor Maven / Gradle / Ivy

/*
 * Copyright (c) 2005, The JUNG Authors
 * All rights reserved.
 * 
 * This software is open-source under the BSD license; see either "license.txt"
 * or https://github.com/jrtom/jung/blob/master/LICENSE for a description.
 * 
 *
 * Created on Apr 12, 2005
 */
package edu.uci.ics.jung.algorithms.layout;

import java.awt.Shape;
import java.awt.geom.Point2D;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import edu.uci.ics.jung.graph.Graph;


/**
 * Simple implementation of PickSupport that returns the vertex or edge
 * that is closest to the specified location.  This implementation
 * provides the same picking options that were available in
 * previous versions of AbstractLayout.
 * 
 * 

No element will be returned that is farther away than the specified * maximum distance. * * @author Tom Nelson * @author Joshua O'Madadhain */ public class RadiusGraphElementAccessor implements GraphElementAccessor { protected double maxDistance; /** * Creates an instance with an effectively infinite default maximum distance. */ public RadiusGraphElementAccessor() { this(Math.sqrt(Double.MAX_VALUE - 1000)); } /** * Creates an instance with the specified default maximum distance. * @param maxDistance the maximum distance at which any element can be from a specified location * and still be returned */ public RadiusGraphElementAccessor(double maxDistance) { this.maxDistance = maxDistance; } /** * Gets the vertex nearest to the location of the (x,y) location selected, * within a distance of maxDistance. Iterates through all * visible vertices and checks their distance from the click. Override this * method to provide a more efficient implementation. * * @param layout the context in which the location is defined * @param x the x coordinate of the location * @param y the y coordinate of the location * @return a vertex which is associated with the location {@code (x,y)} * as given by {@code layout} */ public V getVertex(Layout layout, double x, double y) { return getVertex(layout, x, y, this.maxDistance); } /** * Gets the vertex nearest to the location of the (x,y) location selected, * within a distance of {@code maxDistance}. Iterates through all * visible vertices and checks their distance from the location. Override this * method to provide a more efficient implementation. * * @param layout the context in which the location is defined * @param x the x coordinate of the location * @param y the y coordinate of the location * @param maxDistance the maximum distance at which any element can be from a specified location * and still be returned * @return a vertex which is associated with the location {@code (x,y)} * as given by {@code layout} */ public V getVertex(Layout layout, double x, double y, double maxDistance) { double minDistance = maxDistance * maxDistance; V closest = null; while(true) { try { for(V v : layout.getGraph().getVertices()) { Point2D p = layout.apply(v); double dx = p.getX() - x; double dy = p.getY() - y; double dist = dx * dx + dy * dy; if (dist < minDistance) { minDistance = dist; closest = v; } } break; } catch(ConcurrentModificationException cme) {} } return closest; } public Collection getVertices(Layout layout, Shape rectangle) { Set pickedVertices = new HashSet(); while(true) { try { for(V v : layout.getGraph().getVertices()) { Point2D p = layout.apply(v); if(rectangle.contains(p)) { pickedVertices.add(v); } } break; } catch(ConcurrentModificationException cme) {} } return pickedVertices; } public E getEdge(Layout layout, double x, double y) { return getEdge(layout, x, y, this.maxDistance); } /** * Gets the vertex nearest to the location of the (x,y) location selected, * whose endpoints are < {@code maxDistance}. Iterates through all * visible vertices and checks their distance from the location. Override this * method to provide a more efficient implementation. * * @param layout the context in which the location is defined * @param x the x coordinate of the location * @param y the y coordinate of the location * @param maxDistance the maximum distance at which any element can be from a specified location * and still be returned * @return an edge which is associated with the location {@code (x,y)} * as given by {@code layout} */ public E getEdge(Layout layout, double x, double y, double maxDistance) { double minDistance = maxDistance * maxDistance; E closest = null; while(true) { try { for(E e : layout.getGraph().getEdges()) { // Could replace all this set stuff with getFrom_internal() etc. Graph graph = layout.getGraph(); Collection vertices = graph.getIncidentVertices(e); Iterator vertexIterator = vertices.iterator(); V v1 = vertexIterator.next(); V v2 = vertexIterator.next(); // Get coords Point2D p1 = layout.apply(v1); Point2D p2 = layout.apply(v2); double x1 = p1.getX(); double y1 = p1.getY(); double x2 = p2.getX(); double y2 = p2.getY(); // Calculate location on line closest to (x,y) // First, check that v1 and v2 are not coincident. if (x1 == x2 && y1 == y2) continue; double b = ((y - y1) * (y2 - y1) + (x - x1) * (x2 - x1)) / ((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); // double distance2; // square of the distance if (b <= 0) distance2 = (x - x1) * (x - x1) + (y - y1) * (y - y1); else if (b >= 1) distance2 = (x - x2) * (x - x2) + (y - y2) * (y - y2); else { double x3 = x1 + b * (x2 - x1); double y3 = y1 + b * (y2 - y1); distance2 = (x - x3) * (x - x3) + (y - y3) * (y - y3); } if (distance2 < minDistance) { minDistance = distance2; closest = e; } } break; } catch(ConcurrentModificationException cme) {} } return closest; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy