/** * Gets the node count. */ public int getNodeCount() { return path.size(); }
/** * Returns the point at the center of the bezier path. */ public Point2D.Double getCenter() { double sx = 0; double sy = 0; for (Node p : this) { sx += p.x[0]; sy += p.y[0]; } int n = size(); return new Point2D.Double(sx / n, sy / n); }
/** * Tests if there are more points to read. * @return true if there are more points to read */ @Override public boolean isDone() { return (index >= path.size() + (path.isClosed() ? 2 : 0)); }
/** * 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()); } }
/** * Finds a control point index. * Returns -1 if no control point could be found. * FIXME - Move this to BezierPath */ public int findNode(Point2D.Double p) { BezierPath tp = path; for (int i = 0; i < tp.size(); i++) { BezierPath.Node p2 = tp.get(i); if (p2.x[0] == p.x && p2.y[0] == p.y) { return i; } } return -1; }
/** * Creates a polygon/polyline array of the bezier path which only includes * the C0 control points of the bezier nodes. * <p> * If the bezier path is closed, the array describes a polygon. * If the bezier path is open, the array describes a polyline. * <p> * @return Point array. */ public Point2D.Double[] toPolygonArray() { Point2D.Double[] points = new Point2D.Double[size()]; for (int i = 0, n = size(); i < n; i++) { points[i] = new Point2D.Double(get(i).x[0], get(i).y[0]); } return points; }
/** * Fits a bezier path to the specified list of digitized points. * <p> * This is a convenience method for calling fitCubicSegments(List<Point2D.Double>, double); * * @param digitizedPoints digited points. * @param error the maximal allowed error between the bezier path and the * digitized points. */ public static BezierPath fitBezierPath(BezierPath digitizedPoints, double error) { ArrayList<Point2D.Double> d = new ArrayList<Point2D.Double>(digitizedPoints.size()); for (BezierPath.Node n : digitizedPoints) { d.add(new Point2D.Double(n.x[0], n.y[0])); } return fitBezierPath(d, error); }
@Override public Collection<Handle> createHandles(final int detailLevel) { final LinkedList<Handle> handles = new LinkedList<>(); if (detailLevel != 0) { return super.createHandles(detailLevel); } handles.add(new BezierOutlineHandle(this)); for (int i = 0, n = path.size(); i < n; i++) { handles.add(new PolygonNodeHandle(this, i)); } return handles; }
@Override public Collection<Handle> createHandles(final int detailLevel) { final LinkedList<Handle> handles = new LinkedList<Handle>(); if (detailLevel != 0) { return super.createHandles(detailLevel); } handles.add(new BezierOutlineHandle(this)); for (int i = 0, n = path.size(); i < n; i++) { handles.add(new SwingPolygonNodeHandle(this, i)); } return handles; }
@Override public Collection<Handle> createHandles(final int detailLevel) { final LinkedList<Handle> handles = new LinkedList<>(); if (detailLevel != 0) { return super.createHandles(detailLevel); } handles.add(new BezierOutlineHandle(this)); for (int i = 0, n = path.size(); i < n; i++) { handles.add(new PolygonNodeHandle(this, i)); } return handles; }
public Collection<Handle> createHandles(SVGPathFigure pathFigure, int detailLevel) { LinkedList<Handle> handles = new LinkedList<Handle>(); switch (detailLevel % 2) { case 0: for (int i = 0, n = path.size(); i < n; i++) { handles.add(new BezierNodeHandle(this, i, pathFigure)); } break; case 1: TransformHandleKit.addTransformHandles(this, handles); break; default: break; } return handles; }
public Collection<Handle> createHandles(ODGPathFigure pathFigure, int detailLevel) { LinkedList<Handle> handles = new LinkedList<Handle>(); switch (detailLevel % 2) { case 0: for (int i = 0, n = path.size(); i < n; i++) { handles.add(new BezierNodeHandle(this, i, pathFigure)); } break; case 1: TransformHandleKit.addTransformHandles(this, handles); break; default: break; } return handles; }
@Override public Collection<Handle> createHandles(int detailLevel) { LinkedList<Handle> handles = new LinkedList<Handle>(); switch (detailLevel) { case -1 : // Mouse hover handles handles.add(new BezierOutlineHandle(this, true)); break; case 0 : handles.add(new BezierOutlineHandle(this)); for (int i=0, n = path.size(); i < n; i++) { handles.add(new BezierNodeHandle(this, i)); } break; } return handles; } // CONNECTING
/** Creates a deep copy of the BezierPath. */ @Override public BezierPath clone() { BezierPath that = (BezierPath) super.clone(); for (int i = 0, n = this.size(); i < n; i++) { that.set(i, (Node) this.get(i).clone()); } return that; }
/** * 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)); }
@Override public Collection<Handle> createHandles(int detailLevel) { LinkedList<Handle> handles = new LinkedList<Handle>(); switch (detailLevel % 2) { case -1: // Mouse hover handles handles.add(new BezierOutlineHandle(this, true)); break; case 0: handles.add(new BezierOutlineHandle(this)); for (int i = 0, n = path.size(); i < n; i++) { handles.add(new BezierNodeHandle(this, i)); } break; case 1: TransformHandleKit.addTransformHandles(this, handles); handles.add(new BezierScaleHandle(this)); break; } return handles; }
/** * 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); }
/** * Joins two segments into one if the given Point2D.Double hits a node * of the bezier path. * @return the index of the joined segment or -1 if no segment was joined. */ public int joinSegments(Point2D.Double join, double tolerance) { for (int i = 0; i < size(); i++) { Node p = get(i); if (Geom.length(p.x[0], p.y[0], join.x, join.y) < tolerance) { remove(i); return i; } } return -1; }
/** * 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)); }
/** * Adds the curve to the bezier path. * * @param bezCurve * @param bezierPath */ private static void addCurveTo(Point2D.Double[] bezCurve, BezierPath bezierPath, double errorSquared, boolean connectsCorners) { BezierPath.Node lastNode = bezierPath.get(bezierPath.size() - 1); double error = Math.sqrt(errorSquared); if (connectsCorners && Geom.lineContainsPoint(lastNode.x[0], lastNode.y[0], bezCurve[3].x, bezCurve[3].y, bezCurve[1].x, bezCurve[1].y, error) && Geom.lineContainsPoint(lastNode.x[0], lastNode.y[0], bezCurve[3].x, bezCurve[3].y, bezCurve[2].x, bezCurve[2].y, error)) { bezierPath.lineTo( bezCurve[3].x, bezCurve[3].y); } else { bezierPath.curveTo( bezCurve[1].x, bezCurve[1].y, bezCurve[2].x, bezCurve[2].y, bezCurve[3].x, bezCurve[3].y); } }