Пример #1
0
  /**
   * Returns the vertex, if any, whose shape contains (x, y). If (x,y) is contained in more than one
   * vertex's shape, returns the vertex whose center is closest to the pick point.
   *
   * @param layout the layout instance that records the positions for all vertices
   * @param x the x coordinate of the pick point
   * @param y the y coordinate of the pick point
   * @return the vertex whose shape contains (x,y), and whose center is closest to the pick point
   */
  public V getVertex(Layout<V, E> layout, double x, double y) {

    V closest = null;
    double minDistance = Double.MAX_VALUE;
    Point2D ip =
        vv.getRenderContext()
            .getMultiLayerTransformer()
            .inverseTransform(Layer.VIEW, new Point2D.Double(x, y));
    x = ip.getX();
    y = ip.getY();

    while (true) {
      try {
        for (V v : getFilteredVertices(layout)) {

          Shape shape = vv.getRenderContext().getVertexShapeTransformer().apply(v);
          // get the vertex location
          Point2D p = layout.apply(v);
          if (p == null) continue;
          // 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)) {

            if (style == Style.LOWEST) {
              // return the first match
              return v;
            } else if (style == Style.HIGHEST) {
              // will return the last match
              closest = v;
            } else {

              // return the vertex closest to the
              // center of a vertex shape
              Rectangle2D bounds = shape.getBounds2D();
              double dx = bounds.getCenterX() - ox;
              double dy = bounds.getCenterY() - oy;
              double dist = dx * dx + dy * dy;
              if (dist < minDistance) {
                minDistance = dist;
                closest = v;
              }
            }
          }
        }
        break;
      } catch (ConcurrentModificationException cme) {
      }
    }
    return closest;
  }
Пример #2
0
  /**
   * Retrieves the shape template for <code>e</code> and transforms it according to the positions of
   * its endpoints in <code>layout</code>.
   *
   * @param layout the <code>Layout</code> which specifies <code>e</code>'s endpoints' positions
   * @param e the edge whose shape is to be returned
   * @return the transformed shape
   */
  private Shape getTransformedEdgeShape(Layout<V, E> layout, E e) {
    Pair<V> pair = layout.getGraph().getEndpoints(e);
    V v1 = pair.getFirst();
    V v2 = pair.getSecond();
    boolean isLoop = v1.equals(v2);
    Point2D p1 =
        vv.getRenderContext().getMultiLayerTransformer().transform(Layer.LAYOUT, layout.apply(v1));
    Point2D p2 =
        vv.getRenderContext().getMultiLayerTransformer().transform(Layer.LAYOUT, layout.apply(v2));
    if (p1 == null || p2 == null) return null;
    float x1 = (float) p1.getX();
    float y1 = (float) p1.getY();
    float x2 = (float) p2.getX();
    float y2 = (float) p2.getY();

    // translate the edge to the starting vertex
    AffineTransform xform = AffineTransform.getTranslateInstance(x1, y1);

    Shape edgeShape = vv.getRenderContext().getEdgeShapeTransformer().apply(e);
    if (isLoop) {
      // make the loops proportional to the size of the vertex
      Shape s2 = vv.getRenderContext().getVertexShapeTransformer().apply(v2);
      Rectangle2D s2Bounds = s2.getBounds2D();
      xform.scale(s2Bounds.getWidth(), s2Bounds.getHeight());
      // move the loop so that the nadir is centered in the vertex
      xform.translate(0, -edgeShape.getBounds2D().getHeight() / 2);
    } else {
      float dx = x2 - x1;
      float dy = y2 - y1;
      // rotate the edge to the angle between the vertices
      double theta = Math.atan2(dy, dx);
      xform.rotate(theta);
      // stretch the edge to span the distance between the vertices
      float dist = (float) Math.sqrt(dx * dx + dy * dy);
      xform.scale(dist, 1.0f);
    }

    // transform the edge to its location and dimensions
    edgeShape = xform.createTransformedShape(edgeShape);
    return edgeShape;
  }
Пример #3
0
  /**
   * Returns the vertices whose layout coordinates are contained in <code>Shape</code>. The shape is
   * in screen coordinates, and the graph vertices are transformed to screen coordinates before they
   * are tested for inclusion.
   *
   * @return the <code>Collection</code> of vertices whose <code>layout</code> coordinates are
   *     contained in <code>shape</code>.
   */
  public Collection<V> getVertices(Layout<V, E> layout, Shape shape) {
    Set<V> pickedVertices = new HashSet<V>();

    // remove the view transform from the rectangle
    shape = vv.getRenderContext().getMultiLayerTransformer().inverseTransform(Layer.VIEW, shape);

    while (true) {
      try {
        for (V v : getFilteredVertices(layout)) {
          Point2D p = layout.apply(v);
          if (p == null) continue;

          p = vv.getRenderContext().getMultiLayerTransformer().transform(Layer.LAYOUT, p);
          if (shape.contains(p)) {
            pickedVertices.add(v);
          }
        }
        break;
      } catch (ConcurrentModificationException cme) {
      }
    }
    return pickedVertices;
  }