Here's my contribution, Centripetal Catmul-Rom function - feel free to use it:
Code:
const alpha = 0.5; //set from 0-1
type
TCurveSegment = array of Vector;
var
testsegment: TCurveSegment;
outpoints: TCurveSegment;
function interpolateCurve(points: TCurveSegment; var outpoints: TCurveSegment; amountOfPoints: integer): Vector;
implementation
function GetT(t: single; p0: Vector; p1: Vector): single;
var
a, b, c: single;
begin
a := power((p1.x - p0.x), 2.0) + power((p1.y - p0.y), 2.0);
b := power(a, 0.5);
c := power(b, alpha);
result := (c + t);
end;
// todo: to calculate length, use https://en.wikipedia.org/wiki/Arc_length
// Centripetal Catmul-Rom
// https://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80%93Rom_spline
function interpolateCurve(points: TCurveSegment; var outpoints: TCurveSegment; amountOfPoints: integer): Vector;
var
t0, t1, t2, t3: single;
segment_length: single;
t: single;
A1, A2, A3, B1, B2, C: Vector;
begin
t0 := 0.0;
t1 := GetT(t0, points[0], points[1]);
t2 := GetT(t1, points[1], points[2]);
t3 := GetT(t2, points[2], points[3]);
segment_length := ((t2 - t1) / amountOfPoints);
t := t1;
while (true) do
begin
A1.x := (t1 - t) / (t1 - t0) * points[0].x + (t - t0) / (t1 - t0) * points[1].x;
A1.y := (t1 - t) / (t1 - t0) * points[0].y + (t - t0) / (t1 - t0) * points[1].y;
A2.x := (t2 - t) / (t2 - t1) * points[1].x + (t - t1) / (t2 - t1) * points[2].x;
A2.y := (t2 - t) / (t2 - t1) * points[1].y + (t - t1) / (t2 - t1) * points[2].y;
A3.x := (t3 - t) / (t3 - t2) * points[2].x + (t - t2) / (t3 - t2) * points[3].x;
A3.y := (t3 - t) / (t3 - t2) * points[2].y + (t - t2) / (t3 - t2) * points[3].y;
B1.x := (t2 - t) / (t2 - t0) * A1.x + (t - t0) / (t2 - t0) * A2.x;
B1.y := (t2 - t) / (t2 - t0) * A1.y + (t - t0) / (t2 - t0) * A2.y;
B2.x := (t3 - t) / (t3 - t1) * A2.x + (t - t1) / (t3 - t1) * A3.x;
B2.y := (t3 - t) / (t3 - t1) * A2.y + (t - t1) / (t3 - t1) * A3.y;
C.x := (t2 - t) / (t2 - t1) * B1.x + (t - t1) / (t2 - t1) * B2.x;
C.y := (t2 - t) / (t2 - t1) * B1.y + (t - t1) / (t2 - t1) * B2.y;
setlength(outpoints, length(outpoints) + 1);
outpoints[high(outpoints)] := C;
t := t + segment_length;
if not (t < t2) then
break;
end;
end;
initialization
// setlength(testsegment, 4);
//
// testsegment[0]:= makevector2(5,6);
// testsegment[1]:= makevector2(3,4);
// testsegment[2]:= makevector2(3,2);
// testsegment[3]:= makevector2(5,2);
//
// interpolateCurve(testsegment, outpoints, 10);
//
// info(length(outpoints));
Bookmarks