1 /* 2 * Copyright (c) 2005, the JUNG Project and the Regents of the University of 3 * California All rights reserved. 4 * 5 * This software is open-source under the BSD license; see either "license.txt" 6 * or http://jung.sourceforge.net/license.txt for a description. 7 * 8 * 9 * Created on Apr 12, 2005 10 */ 11 package edu.uci.ics.jung.algorithms.layout3d; 12 13 import java.util.ConcurrentModificationException; 14 15 import javax.vecmath.Point3f; 16 17 18 19 /** 20 * Simple implementation of PickSupport that returns the vertex or edge 21 * that is closest to the specified location. This implementation 22 * provides the same picking options that were available in 23 * previous versions of AbstractLayout. 24 * 25 * <p>No element will be returned that is farther away than the specified 26 * maximum distance. 27 * 28 * @author Tom Nelson 29 * @author Joshua O'Madadhain 30 */ 31 public class RadiusGraphElementAccessor<V, E> implements GraphElementAccessor<V, E> { 32 33 protected double maxDistance; 34 35 /** 36 * Creates an instance with an effectively infinite default maximum distance. 37 */ 38 public RadiusGraphElementAccessor() { 39 this(Math.sqrt(Double.MAX_VALUE - 1000)); 40 } 41 42 /** 43 * Creates an instance with the specified default maximum distance. 44 */ 45 public RadiusGraphElementAccessor(double maxDistance) { 46 this.maxDistance = maxDistance; 47 } 48 49 /** 50 * Gets the vertex nearest to the location of the (x,y) location selected, 51 * within a distance of <tt>maxDistance</tt>. Iterates through all 52 * visible vertices and checks their distance from the click. Override this 53 * method to provde a more efficient implementation. 54 */ 55 public V getVertex(Layout<V,E> layout, Point3f p) { 56 return getVertex(layout, p, this.maxDistance); 57 } 58 59 /** 60 * Gets the vertex nearest to the location of the (x,y) location selected, 61 * within a distance of <tt>maxDistance</tt>. Iterates through all 62 * visible vertices and checks their distance from the click. Override this 63 * method to provde a more efficient implementation. 64 * @param x 65 * @param y 66 * @param maxDistance temporarily overrides member maxDistance 67 */ 68 public V getVertex(Layout<V,E> layout, Point3f p, double maxDistance) { 69 double minDistance = maxDistance * maxDistance; 70 V closest = null; 71 while(true) { 72 try { 73 for(V v : layout.getGraph().getVertices()) { 74 75 Point3f p2 = layout.transform(v); 76 double dist = p.distance(p2); 77 if (dist < minDistance) { 78 minDistance = dist; 79 closest = v; 80 } 81 } 82 break; 83 } catch(ConcurrentModificationException cme) {} 84 } 85 return closest; 86 } 87 88 /** 89 * Gets the edge nearest to the location of the (x,y) location selected. 90 * Calls the longer form of the call. 91 */ 92 // public E getEdge(Layout<V,E> layout, double x, double y) { 93 // return getEdge(layout, x, y, this.maxDistance); 94 // } 95 96 /** 97 * Gets the edge nearest to the location of the (x,y) location selected, 98 * within a distance of <tt>maxDistance</tt>, Iterates through all 99 * visible edges and checks their distance from the click. Override this 100 * method to provide a more efficient implementation. 101 * 102 * @param x 103 * @param y 104 * @param maxDistance temporarily overrides member maxDistance 105 * @return Edge closest to the click. 106 */ 107 // public E getEdge(Layout<V,E> layout, Point3f p, double maxDistance) { 108 // double minDistance = maxDistance * maxDistance; 109 // E closest = null; 110 // while(true) { 111 // try { 112 // for(E e : layout.getGraph().getEdges()) { 113 // 114 // // Could replace all this set stuff with getFrom_internal() etc. 115 // Graph<V, E> graph = layout.getGraph(); 116 // Collection<V> vertices = graph.getIncidentVertices(e); 117 // Iterator<V> vertexIterator = vertices.iterator(); 118 // V v1 = vertexIterator.next(); 119 // V v2 = vertexIterator.next(); 120 // // Get coords 121 // Point3f p1 = layout.transform(v1); 122 // Point3f p2 = layout.transform(v2); 123 // double x = p.getX(); 124 // double y = p.getY(); 125 // double z = p.getZ(); 126 // double x1 = p1.getX(); 127 // double y1 = p1.getY(); 128 // double z1 = p1.getZ(); 129 // double x2 = p2.getX(); 130 // double y2 = p2.getY(); 131 // double z2 = p2.getZ(); 132 // 133 // // Calculate location on line closest to (x,y) 134 // // First, check that v1 and v2 are not coincident. 135 // if (x1 == x2 && y1 == y2 && z1 == z2) 136 // continue; 137 // double b = 138 // ((y - y1) * (y2 - y1) + (x - x1) * (x2 - x1)) 139 // / ((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); 140 // // 141 // double distance2; // square of the distance 142 // if (b <= 0) 143 // distance2 = (x - x1) * (x - x1) + (y - y1) * (y - y1); 144 // else if (b >= 1) 145 // distance2 = (x - x2) * (x - x2) + (y - y2) * (y - y2); 146 // else { 147 // double x3 = x1 + b * (x2 - x1); 148 // double y3 = y1 + b * (y2 - y1); 149 // distance2 = (x - x3) * (x - x3) + (y - y3) * (y - y3); 150 // } 151 // 152 // if (distance2 < minDistance) { 153 // minDistance = distance2; 154 // closest = e; 155 // } 156 // } 157 // break; 158 // } catch(ConcurrentModificationException cme) {} 159 // } 160 // return closest; 161 // } 162 }