/** * Adds a node to the path. * <p> * This is a convenience method for adding a node with a single control * point C0 to the path. */ public void add(double x, double y) { add(new Node(0, x, y, x, y, x, y)); }
BezierPath digitizedPath = new BezierPath(); for (int i = nodeCountBeforeDrag - 1, n = figurePath.size(); i < n; i++) { digitizedPath.add(figurePath.get(nodeCountBeforeDrag - 1)); figurePath.remove(nodeCountBeforeDrag - 1);
/** * Adds a set of nodes to the path. * <p> * Convenience method for adding multiple nodes with a single control point * C0. */ public void addPolyline(Collection<Point2D.Double> points) { for (Point2D.Double c0 : points) { add(new Node(0, c0, c0, c0)); } }
/** * Adds a node to the list of points. */ public void addNode(final int index, BezierPath.Node p) { path.add(index, p); invalidate(); }
/** * Adds a node to the path. * <p> * This is a convenience method for adding a node with a single control * point C0 to the path. */ public void add(Point2D.Double c0) { add(new Node(0, c0, c0, c0)); }
/** * Adds a node to the path. * <p> * This is a convenience method for adding a node with three control points * C0, C1 and C2, and a mask. * * @param ctrlMask An or-combination of C0_MASK,C1_MASK and C2_MASK. * @param c0 The coordinates of the C0 control point. * @param c1 The coordinates of the C1 control point. * @param c2 The coordinates of the C2 control point. */ public void add(int ctrlMask, Point2D.Double c0, Point2D.Double c1, Point2D.Double c2) { add(new Node(ctrlMask, c0, c1, c2)); }
/** * Adds the first node to the bezier path. * <p> * This is a convenience method for adding the first node with a single * control point C0 to the bezier path. */ public void moveTo(double x1, double y1) { if (size() != 0) { throw new IllegalPathStateException("moveTo only allowed when empty"); } Node node = new Node(x1, y1); node.keepColinear = false; add(node); }
/** * Adds a (at least) quadratic curve to the bezier path. * <p> * If the previous node has no C2 control point the line will be quadratic * otherwise the line will be cubic. * <p> * This is a convenience method for adding a node with control point C0 and * C1 (incoming curve) to the bezier path. * <p> * The bezier path must already have at least one node. */ public void quadTo(double x1, double y1, double x2, double y2) { if (size() == 0) { throw new IllegalPathStateException("quadTo only allowed when not empty"); } add(new Node(C1_MASK, x2, y2, x1, y1, x2, y2)); }
/** * 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; }
/** * Adds a (at least) linear 'curve' to the bezier path. * <p> * If the previous node has no C2 control point the line will be straight * (linear), otherwise the line will be quadratic. * <p> * This is a convenience method for adding a node with a single control * point C0. * <p> * The bezier path must already have at least one node. */ public void lineTo(double x1, double y1) { if (size() == 0) { throw new IllegalPathStateException("lineTo only allowed when not empty"); } get(size() - 1).keepColinear = false; add(new Node(x1, y1)); }
/** * 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)); }
/** * Sets all values of this bezier path to that bezier path, so that this * path becomes identical to that path. */ public void setTo(BezierPath that) { while (that.size() < size()) { remove(size() - 1); } for (int i = 0, n = size(); i < n; i++) { get(i).setTo(that.get(i)); } while (size() < that.size()) { add((Node) that.get(size()).clone()); } }
path.add(1, new BezierPath.Node(0, 0)); 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.add(new BezierPath.Node(sp.x,sp.y)); path.add(new BezierPath.Node(ep.x,ep.y)); } else { Rectangle2D.Double sb = start.getBounds(); path.add(new BezierPath.Node(sp.x, (sp.y + ep.y)/2)); path.add(new BezierPath.Node(ep.x, (sp.y + ep.y)/2)); } else if ((soutcode & (Geom.OUT_LEFT | Geom.OUT_RIGHT)) != 0 && (eoutcode & (Geom.OUT_LEFT | Geom.OUT_RIGHT)) != 0) { path.add(new BezierPath.Node((sp.x + ep.x)/2, sp.y)); path.add(new BezierPath.Node((sp.x + ep.x)/2, ep.y)); } else if (soutcode == Geom.OUT_BOTTOM || soutcode == Geom.OUT_TOP) { path.add(new BezierPath.Node(sp.x, ep.y)); } else { path.add(new BezierPath.Node(ep.x, sp.y)); path.add(new BezierPath.Node(ep.x,ep.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(); } }