View Javadoc

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 }