public static CubicCurve2D.Double reverse(CubicCurve2D curv) { return new CubicCurve2D.Double(curv.getX2(), curv.getY2(), curv.getCtrlX2(), curv.getCtrlY2(), curv.getCtrlX1(), curv.getCtrlY1(), curv.getX1(), curv.getY1()); }
private static void subdivide(CubicCurve2D src, CubicCurve2D left, CubicCurve2D right, final double coef) { final double coef1 = coef; final double coef2 = 1 - coef; final double centerxA = src.getCtrlX1() * coef1 + src.getCtrlX2() * coef2; final double centeryA = src.getCtrlY1() * coef1 + src.getCtrlY2() * coef2; final double x1 = src.getX1(); final double y1 = src.getY1(); final double x2 = src.getX2(); final double y2 = src.getY2(); final double ctrlx1 = x1 * coef1 + src.getCtrlX1() * coef1; final double ctrly1 = y1 * coef1 + src.getCtrlY1() * coef1; final double ctrlx2 = x2 * coef1 + src.getCtrlX2() * coef1; final double ctrly2 = y2 * coef1 + src.getCtrlY2() * coef1; final double ctrlx12 = ctrlx1 * coef1 + centerxA * coef1; final double ctrly12 = ctrly1 * coef1 + centeryA * coef1; final double ctrlx21 = ctrlx2 * coef1 + centerxA * coef1; final double ctrly21 = ctrly2 * coef1 + centeryA * coef1; final double centerxB = ctrlx12 * coef1 + ctrlx21 * coef1; final double centeryB = ctrly12 * coef1 + ctrly21 * coef1; left.setCurve(x1, y1, ctrlx1, ctrly1, ctrlx12, ctrly12, centerxB, centeryB); right.setCurve(centerxB, centeryB, ctrlx21, ctrly21, ctrlx2, ctrly2, x2, y2); }
private Point2D evaluate(CubicCurve2D curveData, double t) { double u = 1 - t; return new Point2D.Double( curveData.getX1()*u*u*u + 3*curveData.getCtrlX1()*t*u*u + 3*curveData.getCtrlX2()*t*t*u + curveData.getX2()*t*t*t, curveData.getY1()*u*u*u + 3*curveData.getCtrlY1()*t*u*u + 3*curveData.getCtrlY2()*t*t*u + curveData.getY2()*t*t*t); } }
/** * Report the half-way point on Bézier curve. * * @return the middle of the curve arc */ public Point2D getMiddlePoint () { CubicCurve2D c = getCurve(); return new Point2D.Double( (c.getX1() + (3 * c.getCtrlX1()) + (3 * c.getCtrlX2()) + c.getX2()) / 8, (c.getY1() + (3 * c.getCtrlY1()) + (3 * c.getCtrlY2()) + c.getY2()) / 8); }
/** * Report the point on the curve, located at t = 1-t = 0.5. * It splits the curve length equally. * P: middle of segment P1..P2 * C: middle of segment CP1..CP2 * M: middle of curve * PM = 3/4 * PC * * @param c the provided curve * @return the mid point on curve */ public static Point2D getMidPoint (CubicCurve2D c) { return new Point2D.Double( (c.getX1() + (3 * c.getCtrlX1()) + (3 * c.getCtrlX2()) + c.getX2()) / 8, (c.getY1() + (3 * c.getCtrlY1()) + (3 * c.getCtrlY2()) + c.getY2()) / 8); } }
final public double getSquaredFlatness(CubicCurve2D curve) { double x1=curve.getX1(), y1=curve.getY1(); double x2=curve.getX2(), y2=curve.getY2(); double sqD1=DistUtils.pointToLineSqEucDist(curve.getCtrlX1(), curve.getCtrlY1(), x1, y1, x2, y2); double sqD2=DistUtils.pointToLineSqEucDist(curve.getCtrlX2(), curve.getCtrlY2(), x1, y1, x2, y2); return Math.max(sqD1, sqD2); }
CubicFacade (CubicCurve2D curve) { this.x1 = curve.getX1(); this.y1 = curve.getY1(); this.ctrlx1 = curve.getCtrlX1(); this.ctrly1 = curve.getCtrlY1(); this.ctrlx2 = curve.getCtrlX2(); this.ctrly2 = curve.getCtrlY2(); this.x2 = curve.getX2(); this.y2 = curve.getY2(); }
public static void midPointAndTangentOnCurve( /*in*/CubicCurve2D curve, /*out*/Point2D point, /*out*/Line2D tangent ) { if(null!=curve && (null!=point || null!=tangent)) { double ax0=curve.getX1(), ay0=curve.getY1(); double ax1=curve.getX1(), ay1=curve.getY2(); double cx0=curve.getCtrlX1(), cy0=curve.getCtrlY1(); double cx1=curve.getCtrlX2(), cy1=curve.getCtrlY2(); double ipx0=(cx0+ax0)*0.5, ipy0=(cy0+ay0)*0.5; double ipx1=(cx1+cx0)*0.5, ipy1=(cy1+cy0)*0.5; double ipx2=(ax1+cx1)*0.5, ipy2=(ay1+cy1)*0.5; double tx0=(ipx1+ipx0)*0.5, ty0=(ipy1+ipy0)*0.5; double tx1=(ipx2+ipx1)*0.5, ty1=(ipy2+ipy1)*0.5; if(null!=tangent) { tangent.setLine(tx0, ty0, tx1, ty1); } if(null!=point) { point.setLocation((tx1+tx0)*0.5, (ty1+ty0)*0.5); } } }
double cx1=curve.getCtrlX1(), cy1=curve.getCtrlY1(); double cx2=curve.getCtrlX2(), cy2=curve.getCtrlY2(); double x2=curve.getX1(), y2=curve.getY1();
private static void subdivide(CubicCurve2D src, CubicCurve2D left, CubicCurve2D right, final double coef) { final double coef1 = coef; final double coef2 = 1 - coef; final double centerxA = src.getCtrlX1() * coef1 + src.getCtrlX2() * coef2; final double centeryA = src.getCtrlY1() * coef1 + src.getCtrlY2() * coef2; final double x1 = src.getX1(); final double y1 = src.getY1(); final double x2 = src.getX2(); final double y2 = src.getY2(); final double ctrlx1 = x1 * coef1 + src.getCtrlX1() * coef1; final double ctrly1 = y1 * coef1 + src.getCtrlY1() * coef1; final double ctrlx2 = x2 * coef1 + src.getCtrlX2() * coef1; final double ctrly2 = y2 * coef1 + src.getCtrlY2() * coef1; final double ctrlx12 = ctrlx1 * coef1 + centerxA * coef1; final double ctrly12 = ctrly1 * coef1 + centeryA * coef1; final double ctrlx21 = ctrlx2 * coef1 + centerxA * coef1; final double ctrly21 = ctrly2 * coef1 + centeryA * coef1; final double centerxB = ctrlx12 * coef1 + ctrlx21 * coef1; final double centeryB = ctrly12 * coef1 + ctrly21 * coef1; left.setCurve(x1, y1, ctrlx1, ctrly1, ctrlx12, ctrly12, centerxB, centeryB); right.setCurve(centerxB, centeryB, ctrlx21, ctrly21, ctrlx2, ctrly2, x2, y2); }
public static CubicCurve2D.Double reverse(CubicCurve2D curv) { return new CubicCurve2D.Double(curv.getX2(), curv.getY2(), curv.getCtrlX2(), curv.getCtrlY2(), curv.getCtrlX1(), curv.getCtrlY1(), curv.getX1(), curv.getY1()); }
double x1 = left.getX1(); double y1 = left.getY1(); double cx1 = left.getCtrlX1(); double cy1 = left.getCtrlY1(); double cx2 = right.getCtrlX2();
/** * Converts a cubic Bézier to a quadratic one, using the * <a href="http://www.caffeineowl.com/graphics/2d/vectorial/cubic2quad01.html#mid-point-approx">mid-point * approximation</a> * @param cubic the cubic * @param quad the approximating quadratic. */ static final private void applyMidPointApprox(CubicCurve2D cubic, QuadCurve2D quad) { double a0x=cubic.getX1(), a0y=cubic.getY1(); double a1x=cubic.getX2(), a1y=cubic.getY2(); double p0x=(3*cubic.getCtrlX1()-a0x)/2.0; double p0y=(3*cubic.getCtrlY1()-a0y)/2.0; double p1x=(3*cubic.getCtrlX2()-a1x)/2.0; double p1y=(3*cubic.getCtrlY2()-a1y)/2.0; quad.setCurve(a0x, a0y, (p0x+p1x)/2, (p0y+p1y)/2, a1x, a1y); }
/** * Returns <code>true</code> whenever the square of the * <a href="http://www.caffeineowl.com/graphics/2d/vectorial/cubic2quad01.html#pseudoQuadDist">distance</a> * between the control points of * <tt>0-</tt> and <tt>1-</tt> approximations of the given cubic * multiplied by <tt>1/432=1/(sqrt(3)/36)<sup>2</sup></tt> * is less or equal the {@linkplain #sqTol square} of the requested * precision. */ @Override public boolean shouldSplit(CubicCurve2D c) { double dx=c.getCtrlX2()-c.getCtrlX1(); dx=c.getX2()-c.getX1()-dx-dx-dx; double dy=c.getCtrlY2()-c.getCtrlY1(); dy=c.getY2()-c.getY1()-dy-dy-dy; double sqDist=dx*dx+dy*dy; return (sqDist*BezierUtils.v3div_sq36) <= this.sqTol; } }
public static void pointAndTangentOnCurve( /*in*/double t, /*in*/CubicCurve2D curve, /*out*/Point2D point, /*out*/Line2D tangent ) { if(null!=curve && (null!=point || null!=tangent)) { if(null==tangent) { BezierUtils.pointOnCurve(t, curve, point); } else { double ax0=curve.getX1(), ay0=curve.getY1(); double ax1=curve.getX1(), ay1=curve.getY2(); double cx0=curve.getCtrlX1(), cy0=curve.getCtrlY1(); double cx1=curve.getCtrlX2(), cy1=curve.getCtrlY2(); double ipx0=ax0+(cx0-ax0)*t, ipy0=ay0+(cy0-ay0)*t; double ipx1=cx0+(cx1-cx0)*t, ipy1=cy0+(cy1-cy0)*t; double ipx2=cx1+(ax1-cx1)*t, ipy2=cy1+(ay1-cy1)*t; double tx0=ipx0+(ipx1-ipx0)*t, ty0=ipy0+(ipy1-ipy0)*t; double tx1=ipx1+(ipx2-ipx1)*t, ty1=ipy1+(ipy2-ipy1)*t; tangent.setLine(tx0, ty0, tx1, ty1); if(null!=point) { point.setLocation(tx0+(tx1-tx0)*t, ty0+(ty1-ty0)*t); } } } }
/** * Returns the maximum {@link DistUtils#pointToPointSqEucDist(double, double, double, double) * squared distance} between the two control points and the * segment defined by the curve's anchor points. */ public final double getSquaredFlatness(CubicCurve2D curve) { double sx=curve.getX1(), sy=curve.getY1(); double ex=curve.getX2(), ey=curve.getY2(); double sqDist1=DistUtils.pointToSegSqEucDist( curve.getCtrlX1(), curve.getCtrlY1(), sx, sy, ex, ey ); double sqDist2=DistUtils.pointToSegSqEucDist( curve.getCtrlX2(), curve.getCtrlY2(), sx, sy, ex, ey ); return sqDist1>sqDist2 ? sqDist1 : sqDist2; }
double x0=cubic.getX1(); double x1=cubic.getX2(); double cx0=cubic.getCtrlX1(); double cx1=cubic.getCtrlX2(); double y0=cubic.getY1();
double x0=cubic.getX1(); double x1=cubic.getX2(); double cx0=cubic.getCtrlX1(); double cx1=cubic.getCtrlX2(); double y0=cubic.getY1();
double c0x=curve.getCtrlX1(), c0y=curve.getCtrlY1(); double c1x=curve.getCtrlX2(), c1y=curve.getCtrlY2(); double p1x=curve.getX2(), p1y=curve.getY2();
double c0x=curve.getCtrlX1(), c0y=curve.getCtrlY1(); double c1x=curve.getCtrlX2(), c1y=curve.getCtrlY2(); double p1x=curve.getX2(), p1y=curve.getY2();