Javascript 通过一组N个点绘制曲线,其中N>;2.

Javascript 通过一组N个点绘制曲线,其中N>;2.,javascript,points,bezier,spline,Javascript,Points,Bezier,Spline,我需要用Javascript通过N个大于2的点平滑地绘制一条曲线。我目前正在html5画布对象中使用bezierCurveTo()。我花了很多时间试图找到实现这一点的最佳方法,虽然Catmull Rom样条线听起来很有希望,但我不知道如何将它们画成线。因此,我剩下的是多边形Bézier曲线,需要找到所有中间控制点 我花了很多时间重新学习数学,但我有一个部分有效的例子。这条线有时不是特别平滑,我的控制点在某些向量上被关闭,这是一个问题是我最初的math.stackexchange问题,我要求获得控

我需要用Javascript通过N个大于2的点平滑地绘制一条曲线。我目前正在html5画布对象中使用bezierCurveTo()。我花了很多时间试图找到实现这一点的最佳方法,虽然Catmull Rom样条线听起来很有希望,但我不知道如何将它们画成线。因此,我剩下的是多边形Bézier曲线,需要找到所有中间控制点

我花了很多时间重新学习数学,但我有一个部分有效的例子。这条线有时不是特别平滑,我的控制点在某些向量上被关闭,这是一个问题是我最初的math.stackexchange问题,我要求获得控制点的大部分数学知识

我也会开放的Catmull Rom样条线,但需要一些帮助,我可以如何将它们转换为画布上的线条。我已经找到了资源,但在将其应用于我的需求时又迷失了方向

下面是根据我上面的示例链接创建的图像,演示了如何复制坏的控制点:

非常感谢您提前提供的任何帮助

原始代码:

var a = new Array(points[p-1].x,points[p-1].y);
var b = new Array(points[p].x,points[p].y);
var c = new Array(points[p+1].x,points[p+1].y);

var delta_a = subtract_v(a, b);
var delta_c = subtract_v(c, b);

// Get vector (m) perpendicular bisector
var m = normalize_v( add_v( normalize_v(delta_a),normalize_v(delta_c) ) );

// Get ma and mc
var ma = normalize_v( subtract_v(delta_a,multiply_v(multiply_v(delta_a,m),m) ) );
var mc = normalize_v( subtract_v(delta_c,multiply_v(multiply_v(delta_c,m),m) ) );

// Get the coordinates
points[p].c2x = resolution( b[0] + ( (Math.sqrt( sqr(delta_a[0]) + sqr(delta_a[1]) ) / tightness) * ma[0] ) );
points[p].c2y = resolution( b[1] + ( (Math.sqrt( sqr(delta_a[0]) + sqr(delta_a[1]) ) / tightness) * ma[1] ) );
points[p+1].c1x = resolution( b[0] + ( (Math.sqrt( sqr(delta_c[0]) + sqr(delta_c[1]) ) / tightness) * mc[0] ) );
points[p+1].c1y = resolution( b[1] + ( (Math.sqrt( sqr(delta_c[0]) + sqr(delta_c[1]) ) / tightness) * mc[1] ) );
我不知道“让妈妈和mc”在这里应该做什么。您需要的是一个与角平分线(
m
)正交的向量及其负数

所以这应该是好的:

var delta_a = subtract_v(b, a); // note that we're calculating AB instead of BA
var delta_c = subtract_v(c, b);

// Get an orthogonal to the angle bisector
var m = normalize_v( add_v( normalize_v(delta_a),normalize_v(delta_c) ) );

var ma = [-m[0],-m[1]];
var mc = m;
还要确保删除控制点的
分辨率()

编辑:

您还应该为边缘情况添加回退(例如,
a==B
a==C
,在这种情况下,您的脚本将抛出异常,试图规范化0向量)

亲爱的珍珠母,非常感谢!现在一切都很好。我已经为此挣扎了一个星期。。。想要理解它,而不是仅仅要求一个解决方案。我不知道
ma
mc
是什么,我只是从math.stackexchange答案中得到的。。。但你的解决方案要简单得多。。。而且确实有效!祝你一切顺利!(是的,我将从CPs中删除
resolution()
,我只是想在调试时更清楚地看到坐标)