public void buildVerticalPath() {
    Vector2D start_ = link.getStartWithOffset();
    Vector2D end_ = link.getEndWithOffset();

    if (link.start.x > link.end.x + link.outOffsetLength
        && link.startDirection == Anchor2D.DIRECTION_LEFT) {
      path.add(link.start);
      path.add(link.end.x, link.start.y);
      path.add(link.end);

      link.label.setPosition(
          link.end.x + (link.start.x - link.end.x) * 0.5, link.start.y - LABEL_OFFSET);
    } else if (link.start.x < link.end.x - link.outOffsetLength
        && link.startDirection == Anchor2D.DIRECTION_RIGHT) {
      path.add(link.start);
      path.add(link.end.x, link.start.y);
      path.add(link.end);

      link.label.setPosition(
          link.end.x + (link.start.x - link.end.x) * 0.5, link.start.y - LABEL_OFFSET);
    } else if (link.start.y - GElementRect.DEFAULT_HEIGHT * 0.5 < end_.y + 10) {

      Vector2D p1 = new Vector2D(link.end.x, link.start.y + GElementRect.DEFAULT_HEIGHT * 0.5 + 10);
      Vector2D p2 = new Vector2D(start_.x, p1.y);

      path.add(link.start);
      path.add(start_);
      path.add(p2);
      path.add(p1);
      path.add(link.end);

      link.label.setPosition(p1.add(p2.sub(p1).stretch(0.5)).shift(0, LABEL_OFFSET));
    } else {
      Vector2D ab = start_.sub(link.end);
      Vector2D p1 = new Vector2D(link.end.x, link.end.y + ab.y * 0.5);
      Vector2D p2 = new Vector2D(p1.x + ab.x, p1.y);
      Vector2D p3 = new Vector2D(p2.x, start_.y);

      path.add(link.start);
      path.add(start_);
      path.add(p3);
      path.add(p2);
      path.add(p1);
      path.add(link.end);

      link.label.setPosition(p1.add(p2.sub(p1).stretch(0.5)).shift(0, -LABEL_OFFSET));
    }
  }
 public void updateRightBottom() {
   this.path = link.path;
   if (link.getEndWithOffset().y <= link.start.y) buildVerticalPath();
   else if (link.start.x + link.outOffsetLength < link.end.x - GElementRect.DEFAULT_WIDTH + 10)
     buildHorizontalPath();
   else buildHorizontalLeftPath(false);
 }
  public void buildHorizontalPath() {
    Vector2D start_ = link.getStartWithOffset();
    Vector2D end_ = link.getEndWithOffset();

    Vector2D ab = link.start.sub(end_);
    Vector2D p1 = new Vector2D(end_.x + ab.x * 0.5, end_.y);
    Vector2D p2 = new Vector2D(p1.x, start_.y);

    path.add(link.start);
    path.add(start_);
    path.add(p2);
    path.add(p1);
    path.add(end_);
    path.add(link.end);

    link.label.setPosition(p1.add(p2.sub(p1).stretch(0.5)).shift(LABEL_OFFSET, 0));
  }
  public void buildHorizontalLeftPath(boolean left) {
    Vector2D start_ = link.getStartWithOffset();
    Vector2D end_ = link.getEndWithOffset();

    double farest_x;
    double farest_y = Math.max(end_.y, start_.y + GElementRect.DEFAULT_HEIGHT * 0.5 + 10);

    if (left) farest_x = Math.min(end_.x - GElementRect.DEFAULT_WIDTH * 0.5 - 10, start_.x);
    else farest_x = Math.max(end_.x + GElementRect.DEFAULT_WIDTH * 0.5 + 10, start_.x);

    Vector2D p1 = new Vector2D(end_.x, farest_y);
    Vector2D p2 = new Vector2D(farest_x, p1.y);
    Vector2D p3 = new Vector2D(p2.x, start_.y);

    path.add(link.start);
    path.add(p3);
    path.add(p2);
    path.add(p1);
    path.add(end_);
    path.add(link.end);

    link.label.setPosition(p1.add(p2.sub(p1).stretch(0.5)).shift(0, LABEL_OFFSET));
  }
 public void updateLeftBottom() {
   this.path = link.path;
   if (link.getEndWithOffset().y <= link.start.y) buildVerticalPath();
   else if (link.start.x > link.end.x + GElementRect.DEFAULT_WIDTH + 10) buildHorizontalPath();
   else buildHorizontalLeftPath(true);
 }