public static bool CatmullRomSegmentToCurve4(this PathWriter _writer, double x0, double y0, //p0 //explicit x0 y0 double x1, double y1, //p1 double x2, double y2, //p2 double x3, double y3) //p3 { //just experiment only, //not correct now //https://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80%93Rom_spline //https://stackoverflow.com/questions/30748316/catmull-rom-interpolation-on-svg-paths double t0 = 0.0f, t1 = CatmullRomGetT(t0, x0, y0, x1, y1), t2 = CatmullRomGetT(t1, x1, y1, x2, y2), t3 = CatmullRomGetT(t2, x2, y2, x3, y3); if ((t0 == t1) || (t1 == t2) || (t2 == t3)) { //invalid _writer.LineTo(x1, y1); _writer.LineTo(x2, y2); return(false); } double c1 = (t2 - t1) / (t2 - t0), c2 = (t1 - t0) / (t2 - t0), d1 = (t3 - t2) / (t3 - t1), d2 = (t2 - t1) / (t3 - t1); double m1x = (t2 - t1) * (c1 * (x1 - x0) / (t1 - t0) + c2 * (x2 - x1) / (t2 - t1)); double m2x = (t2 - t1) * (d1 * (x2 - x1) / (t2 - t1) + d2 * (x3 - x2) / (t3 - t2)); double m1y = (t2 - t1) * (c1 * (y1 - y0) / (t1 - t0) + c2 * (y2 - y1) / (t2 - t1)); double m2y = (t2 - t1) * (d1 * (y2 - y1) / (t2 - t1) + d2 * (y3 - y2) / (t3 - t2)); //Q0 = P1 //Q1 = P1 + M1 / 3 //Q2 = P2 - M2 / 3 //Q3 = P2 _writer.LineTo(x1, y1); _writer.Curve4(x1 + m1x / 3, y1 + m1y / 3, x2 - m2x / 3, y2 - m2y / 3, x2, y2); return(true); }
public static void Hermite(this PathWriter pw, double[] xyCoords) { Curve4Points curve4_points = pw._c4_points; pw.MoveTo(xyCoords[0], xyCoords[1]); for (int i = 0; i < xyCoords.Length - (4 * 2);) { Curves.HermiteToBezier( xyCoords[i], xyCoords[i + 1], xyCoords[i + 2], xyCoords[i + 3], xyCoords[i + 4], xyCoords[i + 5], xyCoords[i + 6], xyCoords[i + 7], curve4_points ); pw.Curve4(curve4_points.x1, curve4_points.y1, curve4_points.x2, curve4_points.y2, curve4_points.x3, curve4_points.y3 ); i += 2; } }
public static void CatmulRom(this PathWriter pw, double[] xyCoords) { Curve4Points curve4_points = pw._c4_points; pw.MoveTo(xyCoords[2], xyCoords[3]);//*** for (int i = 0; i < xyCoords.Length - (4 * 2);) { Curves.CatromToBezier( xyCoords[i], xyCoords[i + 1], xyCoords[i + 2], xyCoords[i + 3], xyCoords[i + 4], xyCoords[i + 5], xyCoords[i + 6], xyCoords[i + 7], pw._c4_points ); pw.Curve4(curve4_points.x1, curve4_points.y1, curve4_points.x2, curve4_points.y2, curve4_points.x3, curve4_points.y3 ); i += 2; } }