Pomax / bezierjs

A nodejs and client-side library for (cubic) Bezier curve work
MIT License
1.7k stars 230 forks source link

Split curves do not follow old curve. #210

Open Justinlkirk opened 8 months ago

Justinlkirk commented 8 months ago

First off fantastic library! I have a use case where I need to generate a curve, and then split it into specific lengths before performing a handful of calculations. The issue is that split curves do NOT currently follow the path of the old curve (unless I'm doing something very wrong). I don't mind fixing the issue with your go ahead. I also don't mind submitting another PR with my algorithm for splitting the curve into sections of specific lengths. Its up to you though, thanks again for the great library!

const pathPoints = [startPoint, preHandle, postHandle, endPoint]; const bSpline = new Bezier(pathPoints); const halfSpline = bSpline.split(0, 0.5); const bSpline2 = new Bezier(pathPoints); const secHalf = bSpline2.split(0.5, 1);

const pathPoints = [startPoint, preHandle, postHandle, endPoint]; const bSpline = new Bezier(pathPoints); const halfSpline = bSpline.split(0, 0.5); const secHalf = bSpline.split(0.5, 1);

Both of the above code snippets generate the same lines, and neither follow the original.

justvanrossum commented 8 months ago

Turning this into a concrete example:

const startPoint = { x: 0, y: 0 };
const preHandle = { x: 0, y: 100 };
const postHandle = { x: 100, y: 100 };
const endPoint = { x: 100, y: 0 };

const pathPoints = [startPoint, preHandle, postHandle, endPoint];

const bSpline = new Bezier(pathPoints);

const halfSpline = bSpline.split(0, 0.5);
const secHalf = bSpline.split(0.5, 1);

console.log(halfSpline.points);
console.log(secHalf.points);

The output is:

[ { x: 0, y: 0 }, { x: 0, y: 50 }, { x: 25, y: 75 }, { x: 50, y: 75 } ]
[
  { x: 50, y: 75 },
  { x: 75, y: 75 },
  { x: 100, y: 50 },
  { x: 100, y: 0 }
]

This is exactly what I expect.

It "follows the original" in that the first point of the first split coincides with startPoint, and the last point of the second split coincides with endPoint, and the "middle" point is indeed halfway along the original curve.

What did you expect instead?

justvanrossum commented 8 months ago

I suspect your use of the name bSpline may illustrate a misunderstanding: this is not a B-Spline, but a cubic Bézier curve.