break; case 1: fittedPath.add(new BezierPath.Node(seg.get(0))); break; case 2: if (fittedPath.isEmpty()) { fittedPath.add(new BezierPath.Node(seg.get(0))); default: if (fittedPath.isEmpty()) { fittedPath.add(new BezierPath.Node(seg.get(0)));
return null; } else if (size() == 1) { return get(0).getControlPoint(0); return get(0).getControlPoint(0); } else if (relative >= 1) { return get(size() - 1).getControlPoint(0);
@Override public void updateFigure(final OverlayView view, final BezierFigure figure) { super.updateFigure(view, figure); assert view.getData() instanceof GeneralPathOverlay; final GeneralPathOverlay gpo = (GeneralPathOverlay) view.getData(); final GeneralPathRegionOfInterest gpr = gpo.getRegionOfInterest(); final PathIterator pi = gpr.getGeneralPath().getPathIterator(null); final int nCount = figure.getNodeCount(); int i = 0; final double[] pos = new double[6]; while (!pi.isDone()) { pi.currentSegment(pos); final Node n = new Node(pos[0], pos[1]); if (i < nCount) figure.getNode(i).setTo(n); else figure.addNode(n); pi.next(); i++; } while (i < figure.getNodeCount()) figure.removeNode(i); }
path.add(1, new BezierPath.Node(0,0)); path.get(0).moveTo(sp); path.get(path.size() - 1).moveTo(ep); path.get(1).moveTo(sp.x + slantSize, sp.y); path.get(1).moveTo(sp.x + slantSize, sp.y); } else if ((soutcode & Geom.OUT_LEFT) != 0) { path.get(1).moveTo(sp.x - slantSize, sp.y); } else if ((soutcode & Geom.OUT_BOTTOM) != 0) { path.get(1).moveTo(sp.x, sp.y + slantSize); } else { path.get(1).moveTo(sp.x, sp.y - slantSize); path.get(3).moveTo(ep.x + slantSize, ep.y); } else if ((eoutcode & Geom.OUT_LEFT) != 0) { path.get(3).moveTo(ep.x - slantSize, ep.y); } else if ((eoutcode & Geom.OUT_BOTTOM) != 0) { path.get(3).moveTo(ep.x, ep.y + slantSize); } else { path.get(3).moveTo(ep.x, ep.y - slantSize); path.get(2).moveTo(path.get(1).x[0], path.get(3).y[0]); break; case Geom.OUT_TOP : path.get(2).moveTo(path.get(1).y[0], path.get(3).x[0]); break; case Geom.OUT_LEFT :
path.add(1, new BezierPath.Node(0, 0)); path.get(0).moveTo(sp); path.get(path.size() - 1).moveTo(ep); path.get(1).moveTo(sp.x+shoulderSize, (sp.y+ep.y)/2); path.get(1).x[2] = sp.x + shoulderSize; path.get(1).y[2] = ep.y - shoulderSize; path.get(2).mask = BezierPath.C1_MASK; path.get(2).moveTo((sp.x+ep.x)/2, ep.y-shoulderSize); path.get(2).x[1] = sp.x + shoulderSize; path.get(2).y[1] = ep.y - shoulderSize; path.add(new BezierPath.Node(ep.x, ep.y)); } else { Rectangle2D.Double sb = start.getBounds(); path.add(new BezierPath.Node(BezierPath.C2_MASK, sp.x, sp.y, sp.x, sp.y, sp.x, (sp.y + ep.y) / 2)); path.add(new BezierPath.Node(BezierPath.C1_MASK, ep.x, ep.y, ep.x, (sp.y + ep.y) / 2, ep.x, ep.y)); } else if ((soutcode & (Geom.OUT_LEFT | Geom.OUT_RIGHT)) != 0 && (eoutcode & (Geom.OUT_LEFT | Geom.OUT_RIGHT)) != 0) { path.add(new BezierPath.Node(BezierPath.C2_MASK, sp.x, sp.y, sp.x, sp.y, (sp.x + ep.x) / 2, sp.y)); path.add(new BezierPath.Node(BezierPath.C1_MASK, ep.x, ep.y, (sp.x + ep.x) / 2, ep.y, ep.x, ep.y)); } else if (soutcode == Geom.OUT_BOTTOM || soutcode == Geom.OUT_TOP) { path.add(new BezierPath.Node(BezierPath.C2_MASK, sp.x, sp.y, sp.x, sp.y, sp.x, ep.y)); path.add(new BezierPath.Node(ep.x, ep.y)); } else { path.add(new BezierPath.Node(BezierPath.C2_MASK, sp.x, sp.y, sp.x, sp.y, ep.x, sp.y)); path.add(new BezierPath.Node(ep.x, ep.y));
path.add(1, new BezierPath.Node(0,0)); path.get(0).moveTo(sp); path.get(path.size() - 1).moveTo(ep); path.get(1).moveTo(sp.x + shoulderSize, sp.y); path.get(1).moveTo(sp.x + shoulderSize, sp.y); } else if ((soutcode & Geom.OUT_LEFT) != 0) { path.get(1).moveTo(sp.x - shoulderSize, sp.y); } else if ((soutcode & Geom.OUT_BOTTOM) != 0) { path.get(1).moveTo(sp.x, sp.y + shoulderSize); } else { path.get(1).moveTo(sp.x, sp.y - shoulderSize); path.get(3).moveTo(ep.x + shoulderSize, ep.y); } else if ((eoutcode & Geom.OUT_LEFT) != 0) { path.get(3).moveTo(ep.x - shoulderSize, ep.y); } else if ((eoutcode & Geom.OUT_BOTTOM) != 0) { path.get(3).moveTo(ep.x, ep.y + shoulderSize); } else { path.get(3).moveTo(ep.x, ep.y - shoulderSize); path.get(2).moveTo(path.get(1).x[0], path.get(3).y[0]); break; case Geom.OUT_TOP : path.get(2).moveTo(path.get(1).y[0], path.get(3).x[0]); break; case Geom.OUT_LEFT :
boolean isLinear = true; for (int i = 0, n = bezier.getNodeCount(); i < n; i++) { if (bezier.getNode(i).getMask() != 0) { isLinear = false; break;
BezierPath tempPath = new BezierPath(); Node t1, t2; tempPath.add(t1 = new Node()); tempPath.add(t2 = new Node()); t1.setTo(v1); t2.setTo(v2); tempPath.invalidatePath(); if (tempPath.outlineContains(find, flatness)) { t1.setTo(v1); t2.setTo(v2); tempPath.invalidatePath(); if (tempPath.outlineContains(find, flatness)) {
BezierPath.Node p1 = cappedPath.get(1); Point2D.Double pp; if ((p0.getMask() & BezierPath.C2_MASK) != 0) { pp = p0.getControlPoint(2); } else if ((p1.getMask() & BezierPath.C1_MASK) != 0) { pp = p1.getControlPoint(1); } else { pp = p1.getControlPoint(0); double lineLength = Geom.length(p0.getControlPoint(0), pp); cappedPath.set(0, 0, Geom.cap(pp, p0.getControlPoint(0), -Math.min(radius, lineLength))); if ((p0.getMask() & BezierPath.C1_MASK) != 0) { pp = p0.getControlPoint(1); } else if ((p1.getMask() & BezierPath.C2_MASK) != 0) { pp = p1.getControlPoint(2); } else { pp = p1.getControlPoint(0); double lineLength = Geom.length(p0.getControlPoint(0), pp); cappedPath.set(cappedPath.size() - 1, 0, Geom.cap(pp, p0.getControlPoint(0), -Math.min(radius, lineLength)));
BezierPath tempPath = new BezierPath(); Node t1, t2; tempPath.add(t1 = new Node()); tempPath.add(t2 = new Node()); t1.setTo(v1); t2.setTo(v2); tempPath.invalidatePath(); if (tempPath.outlineContains(find, tolerance)) { t1.setTo(v1); t2.setTo(v2); tempPath.invalidatePath(); if (tempPath.outlineContains(find, tolerance)) {
@Override public void trackEnd(Point anchor, Point lead, int modifiersEx) { final BezierFigure figure = getBezierFigure(); BezierPath.Node oldValue = (BezierPath.Node) oldNode.clone(); BezierPath.Node newValue = figure.getNode(index); if ((modifiersEx & (InputEvent.META_DOWN_MASK | InputEvent.CTRL_DOWN_MASK | InputEvent.ALT_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK)) != 0) {
boolean isLinear = true; for (int i = 0, n = bezier.getNodeCount(); i < n; i++) { if (bezier.getNode(i).getMask() != 0) { isLinear = false; break;
@Override public void trackEnd(Point anchor, Point lead, int modifiersEx) { final BezierFigure f = getOwner(); BezierPath.Node oldValue = (BezierPath.Node) oldNode.clone();; BezierPath.Node newValue = f.getNode(index);
createdFigure.addNode(new BezierPath.Node( creationView.getConstrainer().constrainPoint( creationView.viewToDrawing(anchor))));
/** * 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)); }
/** * Splits the segment at the given Point2D.Double if a segment was hit. * @return the index of the segment or -1 if no segment was hit. */ public int splitSegment(Point2D.Double split, double tolerance) { int i = findSegment(split, tolerance); int nextI = (i + 1) % size(); if (i != -1) { if ((get(i).mask & C2_MASK) == C2_MASK && (get(nextI).mask & C1_MASK) == 0) { // quadto add(i + 1, new Node(C2_MASK, split, split, split)); } else if ((get(i).mask & C2_MASK) == 0 && (get(nextI).mask & C1_MASK) == C1_MASK) { // quadto add(i + 1, new Node(C1_MASK, split, split, split)); } else if ((get(i).mask & C2_MASK) == C2_MASK && (get(nextI).mask & C1_MASK) == C1_MASK) { // cubicto add(i + 1, new Node(C1_MASK | C2_MASK, split, split, split)); } else { // lineto add(i + 1, new Node(split)); } } return i + 1; }
@Override public void updateFigure(final OverlayView view, final BezierFigure figure) { super.updateFigure(view, figure); final PolygonOverlay polygonOverlay = downcastOverlay(view.getData()); final PolygonRegionOfInterest roi = polygonOverlay.getRegionOfInterest(); final int vertexCount = roi.getVertexCount(); while (figure.getNodeCount() > vertexCount) { figure.removeNode(vertexCount); } for (int i = 0; i < vertexCount; i++) { final RealLocalizable vertex = roi.getVertex(i); final double x = vertex.getDoublePosition(0); final double y = vertex.getDoublePosition(1); if (figure.getNodeCount() == i) { figure.addNode(new Node(x, y)); } else { final Node node = figure.getNode(i); node.mask = 0; Arrays.fill(node.x, x); Arrays.fill(node.y, y); } } }
protected void readPoints(DOMInput in) throws IOException { path.clear(); in.openElement("points"); setClosed(in.getAttribute("closed", false)); for (int i = 0, n = in.getElementCount("p"); i < n; i++) { in.openElement("p", i); BezierPath.Node node = new BezierPath.Node( in.getAttribute("mask", 0), in.getAttribute("x", 0d), in.getAttribute("y", 0d), in.getAttribute("c1x", in.getAttribute("x", 0d)), in.getAttribute("c1y", in.getAttribute("y", 0d)), in.getAttribute("c2x", in.getAttribute("x", 0d)), in.getAttribute("c2y", in.getAttribute("y", 0d))); node.keepColinear = in.getAttribute("colinear", true); path.add(node); path.invalidatePath(); in.closeElement(); } in.closeElement(); } }
/** * Splits the segment at the given Point2D.Double if a segment was hit. * @return the index of the segment or -1 if no segment was hit. * * @param split a Point on (or near) a segment of the bezier path * @param tolerance a tolerance, tolerance should take into account * the line width, plus 2 divided by the zoom factor. */ @Override public int splitSegment(Point2D.Double split, double tolerance) { // Apply inverse of transform to point if (get(TRANSFORM) != null) { try { split = (Point2D.Double) get(TRANSFORM).inverseTransform(split, new Point2D.Double()); } catch (NoninvertibleTransformException ex) { System.err.println("Warning: SVGBezierFigure.findSegment. Figure has noninvertible Transform."); } } int i = getBezierPath().findSegment(split, tolerance); if (i != -1) { addNode(i + 1, new BezierPath.Node(split)); } return i + 1; }
@Override public void updateOverlay(final LineFigure figure, final OverlayView view) { super.updateOverlay(figure, view); final LineFigure line = figure; final Overlay overlay = view.getData(); assert overlay instanceof LineOverlay; final LineOverlay lineOverlay = (LineOverlay) overlay; final Node startNode = line.getNode(0); final double x1 = startNode.getControlPoint(0).x; final double y1 = startNode.getControlPoint(0).y; lineOverlay.setLineStart(x1, 0); lineOverlay.setLineStart(y1, 1); final Node endNode = line.getNode(1); final double x2 = endNode.getControlPoint(0).x; final double y2 = endNode.getControlPoint(0).y; lineOverlay.setLineEnd(x2, 0); lineOverlay.setLineEnd(y2, 1); lineOverlay.update(); toolService.reportLine(x1, y1, x2, y2); }