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

edu.uci.ics.jung.visualization.picking.ClosestShapePickSupport Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (c) 2008, 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 24, 2008
 *  
 */
package edu.uci.ics.jung.visualization.picking;

import java.awt.Shape;
import java.awt.geom.Point2D;
import java.util.Collection;
import java.util.ConcurrentModificationException;

import edu.uci.ics.jung.algorithms.layout.GraphElementAccessor;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.visualization.Layer;
import edu.uci.ics.jung.visualization.VisualizationServer;

/**
 * A GraphElementAccessor that finds the closest element to 
 * the pick point, and returns it if it is within the element's shape.
 * This is best suited to elements with convex shapes that do not overlap.
 * It differs from ShapePickSupport in that it only checks
 * the closest element to see whether it contains the pick point.
 * Possible unexpected odd behaviors:
 * 
    *
  • If the elements overlap, this mechanism may pick another element than the one that's * "on top" (rendered last) if the pick point is closer to the center of an obscured vertex. *
  • If element shapes are not convex, then this mechanism may return null * even if the pick point is inside some element's shape, if the pick point is closer * to the center of another element. *
* Users who want to avoid either of these should use ShapePickSupport * instead, which is slower but more flexible. If neither of the above conditions * (overlapping elements or non-convex shapes) is true, then ShapePickSupport * and this class should have the same behavior. */ public class ClosestShapePickSupport implements GraphElementAccessor { protected VisualizationServer vv; protected float pickSize; /** * Creates a ShapePickSupport for the vv * VisualizationServer, with the specified pick footprint. * The VisualizationServer is used to fetch the current * Layout. * @param vv source of the current Layout. * @param pickSize the size of the pick footprint for line edges */ public ClosestShapePickSupport(VisualizationServer vv, float pickSize) { this.vv = vv; this.pickSize = pickSize; } /** * Create a ShapePickSupport with the vv * VisualizationServer and default pick footprint. * The footprint defaults to 2. * @param vv source of the current Layout. */ public ClosestShapePickSupport(VisualizationServer vv) { this.vv = vv; } /** * @see edu.uci.ics.jung.algorithms.layout.GraphElementAccessor#getEdge(edu.uci.ics.jung.algorithms.layout.Layout, double, double) */ public E getEdge(Layout layout, double x, double y) { return null; } /** * @see edu.uci.ics.jung.algorithms.layout.GraphElementAccessor#getVertex(edu.uci.ics.jung.algorithms.layout.Layout, double, double) */ public V getVertex(Layout layout, double x, double y) { // first, find the closest vertex to (x,y) double minDistance = Double.MAX_VALUE; 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) {} } // now check to see whether (x,y) is in the shape for this vertex. // get the vertex shape Shape shape = vv.getRenderContext().getVertexShapeTransformer().apply(closest); // get the vertex location Point2D p = layout.apply(closest); // transform the vertex location to screen coords p = vv.getRenderContext().getMultiLayerTransformer().transform(Layer.LAYOUT, p); double ox = x - p.getX(); double oy = y - p.getY(); if (shape.contains(ox, oy)) return closest; else return null; } /** * @see edu.uci.ics.jung.algorithms.layout.GraphElementAccessor#getVertices(edu.uci.ics.jung.algorithms.layout.Layout, java.awt.Shape) */ public Collection getVertices(Layout layout, Shape rectangle) { // FIXME: RadiusPickSupport and ShapePickSupport are not using the same mechanism! // talk to Tom and make sure I understand which should be used. // in particular, there are some transformations that the latter uses; the latter is also // doing a couple of kinds of filtering. (well, only one--just predicate-based.) // looks to me like the VV could (should) be doing this filtering. (maybe.) // return null; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy