Пример #1
0
  /**
   * Draws a corner relative to the current point of the GeneralPath. Note the radius denotes the
   * distance from the cornerPoint to where the curve starts on the line formed from the cornerPoint
   * to the current point on the gp and where the curve ends on the line from the cornerPoint to the
   * nextCornerPoint. In other words,
   */
  private static void makeCornerTo(
      GeneralPath gp, Point2D cornerPoint, Point2D nextCornerPoint, float radius) {
    Point2D currentPoint = gp.getCurrentPoint();

    // get fractional to the corner where the line first starts to curve
    double distance = currentPoint.distance(cornerPoint);
    double fraction = (distance - radius) / distance;

    // calculate these distance from the current point
    double xDistance = (cornerPoint.getX() - currentPoint.getX()) * fraction;
    double yDistance = (cornerPoint.getY() - currentPoint.getY()) * fraction;

    // draw a line to the point where the line first starts to curve
    lineToRelative(gp, (float) xDistance, (float) yDistance);

    Point2D startCurvePoint = gp.getCurrentPoint();

    // get fractional to the corner where the line first starts to curve
    double distanceFromCornerToNextCorner = cornerPoint.distance(nextCornerPoint);
    double fractionToNextCorner = radius / distanceFromCornerToNextCorner;

    // calculate these distance from the current point
    double xDistanceFromCornerToEndCurve =
        (nextCornerPoint.getX() - cornerPoint.getX()) * fractionToNextCorner;
    double yDistanceFromCornerToEndCurve =
        (nextCornerPoint.getY() - cornerPoint.getY()) * fractionToNextCorner;

    Point2D endCurvePoint =
        new Point2D.Double(
            cornerPoint.getX() + xDistanceFromCornerToEndCurve,
            cornerPoint.getY() + yDistanceFromCornerToEndCurve);

    // finally draw the cornerShape
    cornerShape(
        gp,
        // start at:
        (float) startCurvePoint.getX(),
        (float) startCurvePoint.getY(),
        // corner at:
        (float) cornerPoint.getX(),
        (float) cornerPoint.getY(),
        // end at:
        (float) endCurvePoint.getX(),
        (float) endCurvePoint.getY());

    //    		System.out.println("StartCurve at: " + startCurvePoint);
    //    		System.out.println("Corner at: " + cornerPoint);
    //    		System.out.println("EndCurve at: " + endCurvePoint);
    //    		System.out.println("NextCorner at: " + nextCornerPoint);
  }
Пример #2
0
 /**
  * Draws a curve segment relative to the current point of the GeneralPath.
  *
  * <p>Adds a curved segment, defined by three new points, to the path by drawing a Bezier curve
  * that intersects both the current coordinates and the coordinates (x3, y3), using the specified
  * points (x1, y1) and (x2, y2) as Bezier control points.
  */
 public static void curveTo(
     GeneralPath gp, float x1, float y1, float x2, float y2, float x3, float y3) {
   Point2D currentPoint = gp.getCurrentPoint();
   gp.curveTo(
       x1 + (float) currentPoint.getX(), y1 + (float) currentPoint.getY(),
       x2 + (float) currentPoint.getX(), y2 + (float) currentPoint.getY(),
       x3 + (float) currentPoint.getX(), y3 + (float) currentPoint.getY());
 }
  private void addToGeneralPath(Point2D q, boolean lineTo) {
    Point2D p = gp.getCurrentPoint();
    if (p != null && p.distance(q) < TOLERANCE) {
      return;
    }

    if (lineTo && p != null) {
      try {
        gp.lineTo((float) q.getX(), (float) q.getY());
      } catch (Exception e) {
        gp.moveTo((float) q.getX(), (float) q.getY());
      }
    } else {
      gp.moveTo((float) q.getX(), (float) q.getY());
    }
  }
Пример #4
0
  /**
   * if the edge is reflexive its painted as a cyclic edge if there are 2 controlpoints the
   * connection is painted as a straight line from the source to the targetanchor if there are more
   * as 2 controlpoints the connection path between 2 control points is painted as bezier curve
   */
  @Override
  protected void paintWidget() {

    List<Point> contrPoints = this.getControlPoints();
    int listSize = contrPoints.size();

    Graphics2D gr = getGraphics();

    if (listSize <= 2) {
      if (isReflexive()) { // special case for reflexive connection widgets
        Widget related = this.getTargetAnchor().getRelatedWidget();
        int position = this.edgeBalance(related);
        Rectangle bounds = related.convertLocalToScene(related.getBounds());
        gr.setColor(getLineColor());
        Point first = new Point();
        Point last = new Point();
        double centerX = bounds.getCenterX();
        first.x = (int) (centerX + bounds.width / 4);
        first.y = bounds.y + bounds.height;
        last.x = first.x;
        last.y = bounds.y;

        gr.setStroke(this.getStroke());

        double cutDistance = this.getTargetAnchorShape().getCutDistance();
        double anchorAngle = Math.PI / -3.0;
        double cutX = Math.abs(Math.cos(anchorAngle) * cutDistance);
        double cutY = Math.abs(Math.sin(anchorAngle) * cutDistance);
        int ydiff = first.y - last.y;
        int endy = -ydiff;
        double height = bounds.getHeight();
        double cy = height / 4.0;
        double cx = bounds.getWidth() / 5.0;
        double dcx = cx * 2;
        GeneralPath gp = new GeneralPath();
        gp.moveTo(0, 0);
        gp.quadTo(0, cy, cx, cy);
        gp.quadTo(dcx, cy, dcx, -height / 2.0);
        gp.quadTo(dcx, endy - cy, cy, -(cy + ydiff));
        gp.quadTo(cutX * 1.5, endy - cy, cutX, endy - cutY);

        AffineTransform af = new AffineTransform();
        AnchorShape anchorShape = this.getTargetAnchorShape();

        if (position < 0) {
          first.x = (int) (centerX - bounds.width / 4);
          af.translate(first.x, first.y);
          af.scale(-1.0, 1.0);
          last.x = first.x;
        } else {
          af.translate(first.x, first.y);
        }
        Shape s = gp.createTransformedShape(af);
        gr.draw(s);

        if (last != null) {
          AffineTransform previousTransform = gr.getTransform();
          gr.translate(last.x, last.y);

          if (position < 0) gr.rotate(Math.PI - anchorAngle);
          else gr.rotate(anchorAngle);

          anchorShape.paint(gr, false);
          gr.setTransform(previousTransform);
        }

      } else {
        super.paintWidget();
      }
      return;
    }

    // bezier curve...
    GeneralPath curvePath = new GeneralPath();
    Point lastControlPoint = null;
    double lastControlPointRotation = 0.0;

    Point prev = null;
    for (int i = 0; i < listSize - 1; i++) {
      Point cur = contrPoints.get(i);
      Point next = contrPoints.get(i + 1);
      Point nextnext = null;
      if (i < listSize - 2) {
        nextnext = contrPoints.get(i + 2);
      }

      double len = cur.distance(next);
      double scale = len * BEZIER_SCALE;
      Point bezierFrom = null; // first ControlPoint
      Point bezierTo = null; // second ControlPoint

      if (prev == null) {
        // first point
        curvePath.moveTo(cur.x, cur.y); // startpoint
        bezierFrom = cur;
      } else {
        bezierFrom = new Point(next.x - prev.x, next.y - prev.y);
        bezierFrom = scaleVector(bezierFrom, scale);
        bezierFrom.translate(cur.x, cur.y);
      }

      if (nextnext == null) { // next== last point (curve to)
        lastControlPoint = next;
        bezierTo = next; // set 2nd intermediate point to endpoint
        GeneralPath lastseg = this.subdivide(cur, bezierFrom, bezierTo, next);
        if (lastseg != null) curvePath.append(lastseg, true);
        break;
      } else {
        bezierTo = new Point(cur.x - nextnext.x, cur.y - nextnext.y);
        bezierTo = scaleVector(bezierTo, scale);
        bezierTo.translate(next.x, next.y);
      }

      curvePath.curveTo(
          bezierFrom.x, bezierFrom.y, // controlPoint1
          bezierTo.x, bezierTo.y, // controlPoint2
          next.x, next.y);
      prev = cur;
    }
    Point2D cur = curvePath.getCurrentPoint();
    Point next = lastControlPoint;

    lastControlPointRotation = // anchor anchorAngle
        Math.atan2(cur.getY() - next.y, cur.getX() - next.x);

    Color previousColor = gr.getColor();
    gr.setColor(getLineColor());
    Stroke s = this.getStroke();
    gr.setStroke(s);
    gr.setColor(this.getLineColor());
    gr.draw(curvePath);

    AffineTransform previousTransform = gr.getTransform();
    gr.translate(lastControlPoint.x, lastControlPoint.y);
    gr.rotate(lastControlPointRotation);
    AnchorShape targetAnchorShape = this.getTargetAnchorShape();
    targetAnchorShape.paint(gr, false);
    gr.setTransform(previousTransform);

    // paint ControlPoints if enabled
    if (isPaintControlPoints()) {
      int last = listSize - 1;
      for (int index = 0; index <= last; index++) {
        Point point = contrPoints.get(index);
        previousTransform = gr.getTransform();
        gr.translate(point.x, point.y);
        if (index == 0 || index == last) getEndPointShape().paint(gr);
        else getControlPointShape().paint(gr);
        gr.setTransform(previousTransform);
      }
    }
    gr.setColor(previousColor);
  }
Пример #5
0
  /**
   * Appends path gp2 to gp1. Taken from pre-redesign code.
   *
   * @param reversed is true if the segments are added in reverse order
   */
  public static void appendPath(GeneralPath gp1, GeneralPath gp2, boolean reversed) {
    ArrayList<Number[]> points =
        new ArrayList<
            Number[]>(); // Each element is an array consisting of one Integer and six Floats

    PathIterator i = gp2.getPathIterator(new AffineTransform());

    float[] segment = new float[] {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};

    float leftmost = Float.POSITIVE_INFINITY;

    while (!i.isDone()) {
      int type = i.currentSegment(segment);
      i.next();

      points.add(
          new Number[] {
            new Integer(type),
            new Float(segment[0]),
            new Float(segment[1]),
            new Float(segment[2]),
            new Float(segment[3]),
            new Float(segment[4]),
            new Float(segment[5])
          });
    }

    if (reversed) {
      float deltaX = (float) gp1.getCurrentPoint().getX();
      float deltaY = (float) gp1.getCurrentPoint().getY();

      Object[] typeAndPoints = points.get(points.size() - 1);

      int type = ((Integer) typeAndPoints[0]).intValue();

      if (type == PathIterator.SEG_LINETO) {
        deltaX -= ((Float) typeAndPoints[1]).floatValue();
        deltaY -= ((Float) typeAndPoints[2]).floatValue();
      } else if (type == PathIterator.SEG_QUADTO) {
        deltaX -= ((Float) typeAndPoints[3]).floatValue();
        deltaY -= ((Float) typeAndPoints[4]).floatValue();
      } else if (type == PathIterator.SEG_CUBICTO) {
        deltaX -= ((Float) typeAndPoints[5]).floatValue();
        deltaY -= ((Float) typeAndPoints[6]).floatValue();
      } else {
        assert false : type;
      }

      for (int j = points.size() - 1; j >= 1; j--) {
        typeAndPoints = points.get(j);

        type = ((Integer) typeAndPoints[0]).intValue();
        float x1 = ((Float) typeAndPoints[1]).floatValue();
        float y1 = ((Float) typeAndPoints[2]).floatValue();
        float x2 = ((Float) typeAndPoints[3]).floatValue();
        float y2 = ((Float) typeAndPoints[4]).floatValue();

        float prevX = 0.0f, prevY = 0.0f;

        int prevType = ((Integer) points.get(j - 1)[0]).intValue();

        if ((prevType == PathIterator.SEG_MOVETO) || (prevType == PathIterator.SEG_LINETO)) {
          prevX = ((Float) points.get(j - 1)[1]).floatValue();
          prevY = ((Float) points.get(j - 1)[2]).floatValue();
        } else if (prevType == PathIterator.SEG_QUADTO) {
          prevX = ((Float) points.get(j - 1)[3]).floatValue();
          prevY = ((Float) points.get(j - 1)[4]).floatValue();
        } else if (prevType == PathIterator.SEG_CUBICTO) {
          prevX = ((Float) points.get(j - 1)[5]).floatValue();
          prevY = ((Float) points.get(j - 1)[6]).floatValue();
        } else {
          assert false : prevType;
        }

        leftmost = Math.min(leftmost, prevX + deltaX);

        if ((type == PathIterator.SEG_MOVETO) || (type == PathIterator.SEG_LINETO)) {
          gp1.lineTo(prevX + deltaX, prevY + deltaY);
        } else if (type == PathIterator.SEG_QUADTO) {
          gp1.quadTo(x1 + deltaX, y1 + deltaY, prevX + deltaX, prevY + deltaY);
        } else if (type == PathIterator.SEG_CUBICTO) {
          gp1.curveTo(
              x2 + deltaX, y2 + deltaY, x1 + deltaX, y1 + deltaY, prevX + deltaX, prevY + deltaY);
        } else {
          assert false : type;
        }
      }
    } else // Not reversed
    {
      float deltaX = (float) gp1.getCurrentPoint().getX() - ((Float) points.get(0)[1]).floatValue();
      float deltaY = (float) gp1.getCurrentPoint().getY() - ((Float) points.get(0)[2]).floatValue();

      for (int j = 1; j < points.size(); j++) {
        Object[] typeAndPoints = points.get(j);

        int type = ((Integer) typeAndPoints[0]).intValue();
        float x1 = ((Float) typeAndPoints[1]).floatValue();
        float y1 = ((Float) typeAndPoints[2]).floatValue();
        float x2 = ((Float) typeAndPoints[3]).floatValue();
        float y2 = ((Float) typeAndPoints[4]).floatValue();
        float x3 = ((Float) typeAndPoints[5]).floatValue();
        float y3 = ((Float) typeAndPoints[6]).floatValue();

        if (type == PathIterator.SEG_MOVETO) {
        } else if (type == PathIterator.SEG_LINETO) {
          gp1.lineTo(x1 + deltaX, y1 + deltaY);

          leftmost = Math.min(leftmost, x1 + deltaX);
        } else if (type == PathIterator.SEG_QUADTO) {
          gp1.quadTo(x1 + deltaX, y1 + deltaY, x2 + deltaX, y2 + deltaY);

          leftmost = Math.min(leftmost, x2 + deltaX);
        } else if (type == PathIterator.SEG_CUBICTO) {
          gp1.curveTo(x1 + deltaX, y1 + deltaY, x2 + deltaX, y2 + deltaY, x3 + deltaX, y3 + deltaY);

          leftmost = Math.min(leftmost, x3 + deltaX);
        } else {
          assert false : type;
        }
      }
    }
  }
Пример #6
0
 /** Draws a line segment relative to the current point of the GeneralPath. */
 public static void lineToRelative(GeneralPath gp, float x, float y) {
   Point2D currentPoint = gp.getCurrentPoint();
   gp.lineTo((float) currentPoint.getX() + x, (float) currentPoint.getY() + y);
 }