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

RAN*_*GER 6 javascript bezier spline points

我需要使用Javascript平滑地绘制N点> N> 2的曲线.我目前在html5 canvas对象中使用bezierCurveTo().我投入了大量的时间来寻找实现这一目标的最佳方法,虽然Catmull-Rom Splines看起来很有前途,但我并不知道将它们画成线条的方法.因此,我留下了Poly-lineBézier曲线,需要找到所有中间控制点.

我花了很多时间重新学习数学,但我在这里有一个部分工作的例子.这条线有时不是特别平滑,并且我的控制点在某些矢量关闭时出现问题.是我最初的math.stackexchange问​​题,我要求获得控制点的大部分数学.

我也会对Catmull-Rom样条线开放,但需要一些帮助才能将它们转换为画布上的线条.我找到了这个资源,但是再次将它应用到我的需求中.

下面是我上面的示例链接创建的图像,说明了如何复制控制点:

在此输入图像描述

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

use*_*621 4

原始代码:

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] ) );
Run Code Online (Sandbox Code Playgroud)

我不知道“Get ma and 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;
Run Code Online (Sandbox Code Playgroud)

还要确保删除resolution()控制点。

编辑:
您还应该为边缘情况添加后备(例如,A==BA==C,在这种情况下您的脚本将抛出异常,尝试标准化 0 向量)