123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- package de.tu_darmstadt.informatik.tk.scopviz.main;
- import java.util.Iterator;
- import org.graphstream.ui.geom.Point3;
- import org.graphstream.ui.graphicGraph.GraphPosLengthUtils;
- import org.graphstream.ui.view.Camera;
- import de.tu_darmstadt.informatik.tk.scopviz.graphs.GraphManager;
- import de.tu_darmstadt.informatik.tk.scopviz.graphs.MyEdge;
- import de.tu_darmstadt.informatik.tk.scopviz.graphs.MyNode;
- /**
- * This class contains helpful static functions.
- *
- * @author Matthias Wilhelm
- * @version 1.0
- */
- public final class EdgeSelectionHelper {
- /**
- * Private Constructor to prevent instantiation. private
- * EdgeSelectionHelper(){}
- *
- * /** Width in pixels for which the edge selection triggers.
- */
- private static final int EDGE_SELECTION_WIDTH = 5;
- /**
- * Precalculates pi / 2.
- */
- private static final double HALF_PI = Math.PI / 2;
- private EdgeSelectionHelper() {
- }
- // TODO optional: only update if view has changed
- /**
- * Returns the closest Edge in the current Graph to a given position. It
- * allows for an inaccuracy of around {@value #EDGE_SELECTION_WIDTH}px
- *
- * @param pos
- * The position. Expects a <b>Point3</b>, but only uses the x and
- * y coordinates
- * @return the closest Edge if a valid Edge exists, returns <b>null</b>
- * otherwise
- */
- public static MyEdge getClosestEdge(Point3 pos) {
- Camera cam = Main.getInstance().getGraphManager().getView().getCamera();
- // gets to points within a fixed distance of each other and calculates
- // the gu of those points
- Point3 min = cam.transformPxToGu(0, 0);
- Point3 max = cam.transformPxToGu(EDGE_SELECTION_WIDTH, EDGE_SELECTION_WIDTH);
- // calculates the approximate distance by taken the maximum of the
- // absolute Distances of the x's or y's
- double dist = Math.max(Math.abs(max.x - min.x), Math.abs(max.y - min.y));
- // calls the actual calculation
- return getClosestEdge(pos, dist);
- }
- /**
- * Returns the closest Edge in the current Graph to a given position within
- * the given maxDistance.
- *
- * @param pos
- * The position. Expects a <b>Point3</b>, but only uses the x and
- * y coordinates
- * @param maxDistance
- * the maximum distance (in gu) the edge may be away from the
- * position to be considered as a valid edge
- * @return the closest Edge if a valid Edge exists, returns <b>null</b>
- * otherwise
- */
- public static MyEdge getClosestEdge(Point3 pos, double maxDistance) {
- double x0 = pos.x;
- double y0 = pos.y;
- // keeps track of the current smallest distance to an edge;
- // initializes to the given maxDistance
- double dist = maxDistance;
- // keeps track of the current closest edge
- MyEdge result = null;
- GraphManager gm = Main.getInstance().getGraphManager();
- // Iterates over every edge, calculates the distance and updates the
- // best edge and corresponding distance
- for (Iterator<MyEdge> iterator = gm.getGraph().getEdgeIterator(); iterator.hasNext();) {
- MyEdge edge = iterator.next();
- // Get the positions of the nodes of the currently selected edge.
- double[] n1 = GraphPosLengthUtils.nodePosition(edge.getNode0());
- double[] n2 = GraphPosLengthUtils.nodePosition(edge.getNode1());
- // Extract the x and y values of the positions of the nodes
- double x1 = n1[0];
- double y1 = n1[1];
- double x2 = n2[0];
- double y2 = n2[1];
- // Calculate the distance between the nodes
- // Naming convention is view node 0 as A, node 1 as B and the point
- // as C in a triangle
- double c = distance(x1, y1, x2, y2); // Distance Node0 Node1
- // Calculate the distance between the edge and the point
- double cdist = Math.abs((y2 - y1) * x0 - (x2 - x1) * y0 + x2 * y1 - y2 * x1) / c;
- // Check if the edge is closer than the currently stored one
- if (cdist < dist) {
- // Calculate the distances from each node to the point
- double a = distance(x0, y0, x2, y2); // Distance Point Node0
- double b = distance(x0, y0, x1, y1); // Distance Point Node1
- // Precalculate the squares of the distances for later use
- double b2 = b * b;
- double a2 = a * a;
- double c2 = c * c;
- // Calculates the inner angles off the triangle
- double alpha = Math.acos((b2 + c2 - a2) / (2 * b * c));
- double beta = Math.acos((a2 + c2 - b2) / (2 * a * c));
- // Check if the point is actually visually next to the edge by
- // checking if both inner angles are less than 90°
- if (alpha <= HALF_PI && beta <= HALF_PI) {
- dist = cdist;
- result = edge;
- }
- }
- }
- return result;
- }
- /**
- * Calculates the distance between two given Nodes.
- *
- * @param a
- * Node 1
- * @param b
- * Node 2
- * @return the distance between the two Nodes as a double
- */
- public static double distance(MyNode a, MyNode b) {
- double[] n1 = GraphPosLengthUtils.nodePosition(a);
- double[] n2 = GraphPosLengthUtils.nodePosition(b);
- return distance(n1[0], n1[1], n2[0], n2[1]);
- }
- /**
- * Calculates the distance between a x,y position and a Node.
- *
- * @param x0
- * x cord of the position
- * @param y0
- * y cord of the position
- * @param a
- * the Node
- * @return the distance between the position and the Node as a double
- */
- public static double distance(double x0, double y0, MyNode a) {
- double[] n1 = GraphPosLengthUtils.nodePosition(a);
- return distance(x0, y0, n1[0], n1[1]);
- }
- /**
- * Calculates the distance between two x,y positions.
- *
- * @param x0
- * x cord of the first position
- * @param y0
- * y cord of the first position
- * @param x1
- * x cord of the second position
- * @param y1
- * y cord of the second position
- * @return the distance between the two positions as a double
- */
- public static double distance(double x0, double y0, double x1, double y1) {
- return Math.sqrt(Math.pow(y0 - y1, 2) + Math.pow(x0 - x1, 2));
- }
- }
|