@Override public Rectangle2D.Double getFigureDrawingArea() { Rectangle2D.Double b = super.getFigureDrawingArea(); // Grow for connectors Geom.grow(b, 10d, 10d); return b; }
@Override public void trackStart(Point anchor, int modifiersEx) { location = new Point(anchor.x, anchor.y); restoreData = getOwner().getTransformRestoreData(); transform = new AffineTransform(); center = getCenter(); Point2D.Double anchorPoint = view.viewToDrawing(anchor); startTheta = Geom.angle(center.x, center.y, anchorPoint.x, anchorPoint.y); startLength = Geom.length(center.x, center.y, anchorPoint.x, anchorPoint.y); }
/** * This is a default implementation that chops the point at the rectangle * returned by getBounds() of the figure. * <p> * Figures which have a non-rectangular shape need to override this method. * <p> * FIXME Invoke chop on each child and return the closest point. */ public Point2D.Double chop(Point2D.Double from) { Rectangle2D.Double r = getBounds(); return Geom.angleToPoint(r, Geom.pointToAngle(r, from)); }
/** * Gets the point on an oval that corresponds to the given angle. */ public static Point ovalAngleToPoint(Rectangle r, double angle) { Point center = Geom.center(r); Point p = Geom.polarToPoint(angle, r.width / 2, r.height / 2); return new Point(center.x + p.x, center.y + p.y); }
/** * Gets the point on an oval that corresponds to the given angle. */ public static Point2D.Double ovalAngleToPoint(Rectangle2D.Double r, double angle) { Point2D.Double center = Geom.center(r); Point2D.Double p = Geom.polarToPoint2D(angle, r.width / 2, r.height / 2); return new Point2D.Double(center.x + p.x, center.y + p.y); }
protected Point2D.Double chop(Figure target, Point2D.Double from) { target = getConnectorTarget(target); Rectangle2D.Double r = target.getBounds(); if (target.get(STROKE_COLOR) != null) { double grow; switch (target.get(STROKE_PLACEMENT)) { case CENTER: default : grow = AttributeKeys.getStrokeTotalWidth(target) / 2d; break; case OUTSIDE : grow = AttributeKeys.getStrokeTotalWidth(target); break; case INSIDE : grow = 0d; break; } Geom.grow(r, grow, grow); } return Geom.angleToPoint(r, Geom.pointToAngle(r, from)); }
Geom.grow(r, growx, growy); double ang = Geom.pointToAngle(r, from); rp = Geom.intersect(p1.x, p1.y, p2.x, p2.y, c1.x, c1.y, from.x, from.y); } else if (ang > 1.575 && ang < 3.14) { rp = Geom.intersect(p2.x, p2.y, p3.x, p3.y, c1.x, c1.y, from.x, from.y); } else if (ang > -3.14 && ang < -1.575) { rp = Geom.intersect(p3.x, p3.y, p4.x, p4.y, c1.x, c1.y, from.x, from.y); } else if (ang > -1.57 && ang < 0) { rp = Geom.intersect(p4.x, p4.y, p1.x, p1.y, c1.x, c1.y, from.x, from.y); rp = Geom.angleToPoint(r, ang);
@Override protected Point2D.Double chop(Figure target, Point2D.Double from) { target = getConnectorTarget(target); Rectangle2D.Double r = target.getBounds(); if (getStrokeColor(target) != null) { double grow; switch (target.get(STROKE_PLACEMENT)) { case CENTER: default : grow = getStrokeTotalWidth(target) / 2d; break; case OUTSIDE : grow = getStrokeTotalWidth(target); break; case INSIDE : grow = 0f; break; } Geom.grow(r, grow, grow); } double angle = Geom.pointToAngle(r, from); return Geom.ovalAngleToPoint(r, angle); } }
@Override public Connector findConnector(Point2D.Double p, ConnectionFigure figure) { // return closest connector double min = Double.MAX_VALUE; Connector closest = null; for (Connector c : connectors) { Point2D.Double p2 = Geom.center(c.getBounds()); double d = Geom.length2(p.x, p.y, p2.x, p2.y); if (d < min) { min = d; closest = c; } } return closest; }
/** * Gets the connection point. Override when the connector * does not need to distinguish between the start and end * point of a connection. */ protected Point2D.Double findPoint(ConnectionFigure connection) { return Geom.center(getBounds()); }
return Geom.length(xa, ya, xc, yc);
v2 = get(i + 1); if (v1.mask == 0 && v2.mask == 0) { if (Geom.lineContainsPoint(v1.x[0], v1.y[0], v2.x[0], v2.y[0], find.x, find.y, flatness)) { relativeLen += Geom.length(v1.x[0], v1.y[0], find.x, find.y); return relativeLen / len; } else { relativeLen += Geom.length(v1.x[0], v1.y[0], v2.x[0], v2.y[0]); tempPath.invalidatePath(); if (tempPath.outlineContains(find, flatness)) { relativeLen += Geom.length(v1.x[0], v1.y[0], find.x, find.y); return relativeLen / len; } else { relativeLen += Geom.length(v1.x[0], v1.y[0], v2.x[0], v2.y[0]); v2 = get(0); if (v1.mask == 0 && v2.mask == 0) { if (Geom.lineContainsPoint(v1.x[0], v1.y[0], v2.x[0], v2.y[0], find.x, find.y, flatness)) { relativeLen += Geom.length(v1.x[0], v1.y[0], find.x, find.y); return relativeLen / len; tempPath.invalidatePath(); if (tempPath.outlineContains(find, flatness)) { relativeLen += Geom.length(v1.x[0], v1.y[0], find.x, find.y); return relativeLen / len;
double lineLength = Geom.length(p0.getControlPoint(0), pp); cappedPath.set(0, 0, Geom.cap(pp, p0.getControlPoint(0), -Math.min(radius, lineLength))); double lineLength = Geom.length(p0.getControlPoint(0), pp); cappedPath.set(cappedPath.size() - 1, 0, Geom.cap(pp, p0.getControlPoint(0), -Math.min(radius, lineLength)));
/** * Returns a point on the edge of the bezier path which crosses the line * from the center of the bezier path to the specified point. * If no edge crosses the line, the nearest C0 control point is returned. */ public Point2D.Double chop(Point2D.Double p) { return Geom.chop(this, p); }
@Override public java.util.List<Figure> findFiguresWithin(Rectangle2D.Double bounds) { LinkedList<Figure> contained = new LinkedList<Figure>(); for (Figure f : children) { Rectangle2D.Double r = f.getBounds(); if (f.get(TRANSFORM) != null) { Rectangle2D rt = f.get(TRANSFORM).createTransformedShape(r).getBounds2D(); r = (rt instanceof Rectangle2D.Double) ? (Rectangle2D.Double) rt : new Rectangle2D.Double(rt.getX(), rt.getY(), rt.getWidth(), rt.getHeight()); } if (f.isVisible() && Geom.contains(bounds, r)) { contained.add(f); } } return contained; }
@Override protected Point2D.Double chop(Figure target, Point2D.Double from) { return Geom.angleToPoint(target.getBounds(), angle); }
/** * Adds a cubic curve to the bezier path. * <p> * This is a convenience method for adding a node with control point C0 and * C1 (incoming curve) to the bezier path, and also specifying the control * point C2 (outgoing curve) of the previous node. * <p> * The bezier path must already have at least one node. */ public void curveTo(double x1, double y1, double x2, double y2, double x3, double y3) { if (size() == 0) { throw new IllegalPathStateException("curveTo only allowed when not empty"); } Node lastPoint = get(size() - 1); lastPoint.mask |= C2_MASK; lastPoint.x[2] = x1; lastPoint.y[2] = y1; if ((lastPoint.mask & C1C2_MASK) == C1C2_MASK) { lastPoint.keepColinear = Math.abs( Geom.angle(lastPoint.x[0], lastPoint.y[0], lastPoint.x[1], lastPoint.y[1]) - Geom.angle(lastPoint.x[2], lastPoint.y[2], lastPoint.x[0], lastPoint.y[0])) < 0.001; } add(new Node(C1_MASK, x3, y3, x2, y2, x3, y3)); }
innerWidth, currentCorners); intersect = Geom.intersect( prevCorners[0], prevCorners[1], prevCorners[4], prevCorners[5], intersect = Geom.intersect( prevCorners[2], prevCorners[3], prevCorners[6], prevCorners[7], bp.get(i + 1).x[0], bp.get(i + 1).y[0], innerWidth, tmp); intersect = Geom.intersect( prevCorners[0], prevCorners[1], prevCorners[4], prevCorners[5], intersect = Geom.intersect( prevCorners[2], prevCorners[3], prevCorners[6], prevCorners[7], intersect = Geom.intersect( prevCorners[0], prevCorners[1], prevCorners[4], prevCorners[5], intersect = Geom.intersect( prevCorners[2], prevCorners[3], prevCorners[6], prevCorners[7],
break; Geom.grow(r, grow, grow); return Geom.angleToPoint(r, Geom.pointToAngle(r, from));