理解三次插值的实现
understand implementation of cubic interpolation
我想在javascript中实现三次插值,用canvas画一条曲线。这个想法是在 canvas 中单击以添加点,并且每次更改都会调用一个重绘函数,该函数计算要在 canvas 中为给定的单击点绘制的点。
我找到了一些例子,例如:
http://snipplr.com/view/727/cubic-interpolation/
http://www.paulinternet.nl/?page=bicubic
http://dzone.com/snippets/cubic-interpolation
但我不知道如何使用此代码:/
根据这个简单的例子给4分:
float cubic_interpolate( float y0, float y1, float y2, float y3, float mu ) {
float a0, a1, a2, a3, mu2;
mu2 = mu*mu;
a0 = y3 - y2 - y0 + y1; //p
a1 = y0 - y1 - a0;
a2 = y2 - y0;
a3 = y1;
return ( a0*mu*mu2 + a1*mu2 + a2*mu + a3 );
}
第一个我不明白的是参数。我有 4 个点和一个介于 0 和 1 之间的值。那么我的 return 值是多少?或者更好的是什么是 mu? y0 ... y3 只是点的 y 值还是像 y0[0] 是 x 和 y0[1] 是 y 这样的点?我需要的是一种算法,它有一些点和一个 x 值作为参数,return 值应该是 y 值。
类似的东西:
function calculateCubic( points ){
var pointsToDraw = [];
getValue(p1,p2,p3,p4,xCoordinate){
var yCoordinate;
yCoordinate = ...
...
return yCoordinate;
}
for(var i = 0; i<p.length-3;i++){
var stepLen = ( p[i+1][0] - p[i][0] ) / 100;
for( var s = p[i][0]; s <= p[i+1][0] ;s += stepLen ){
pointsToDraw[pointsToDraw.length] = getValue(p[i],p[i+1],p[i+2],p[i+3],p[i][0]);
}
}
return pointsToDraw;
}
任何人都可以帮助我理解代码片段并将它们用于我的问题吗?
多谢指教!
看起来代码对一组数据点进行了三次插值,返回的是 Catmull-Rom 样条。
你最好使用贝塞尔样条曲线,在我看来它更容易实现。
mu 是给出曲线位置的参数。要在曲线上绘制一组 10 个点,请使用相同的 y0、y1、y2、y3 值和 mu 0、0.1、0.2、0.3、... 1.0 的值。
要了解此处的 y 值,请查看将 mu=0 和 mu=1 放入函数时会发生什么。 mu=0 函数 returns y1。当 mu=1 时,函数 returns y2。我们看到这种样条曲线穿过中间的两个控制点。
正如 Mark 所说,这不是最容易使用的样条曲线。你最好使用贝塞尔样条曲线。他们的一个非常好的页面是 http://pomax.github.io/bezierinfo/. There is also a bezierCurveTo
function in the javascript canvas which makes them easy to use API doc.
您发布的链接中的示例代码都是从 4 个点或从 2 个点和 2 个导数的三次插值。
'mu' 是您要计算 y 值的参数。输入的y0、y1、y2、y3是4个输入点的y坐标。您可以通过将 x0、x1、x2 和 x3 传递给函数来执行相同的操作以评估参数 'mu' 处的 x 值。
你说你想要一个将 x 值作为参数输入并返回 y 值作为输出的函数。这只有在您以显式形式表示曲线时才有可能,即 y=f(x)。但是,显式形式无法表示具有多个 y 值和相同 x 值的曲线。因此,它们通常不是表示曲线的好方法。参数形式是表示曲线的更好方法。例如,2D 曲线 C(t) 表示为 C(t) = (x(t), y(t)) 或 3D 曲线可以表示为 C(t)=(x(t), y( t), z(t)).将一个完整的圆表示为 (x(t), y(t))=(rcos(t),rsin(t)) 是参数形式的一个很好的例子。
如果要绘制连接一系列数据点的平滑曲线,最简单的方法是实现 Catmull Rom 样条或 Overhauser 样条。它们都是三次 Hermite 曲线的特殊形式。阅读有关三次 Hermite 曲线 here 的维基百科页面并转到同一页面中的 Catmull Rom 样条部分,您将能够知道如何创建插值数据点的 Catmull Rom 样条以及如何评估它以获得(x, y) 值在 canvas.
中绘制样条曲线
我想在javascript中实现三次插值,用canvas画一条曲线。这个想法是在 canvas 中单击以添加点,并且每次更改都会调用一个重绘函数,该函数计算要在 canvas 中为给定的单击点绘制的点。
我找到了一些例子,例如:
http://snipplr.com/view/727/cubic-interpolation/
http://www.paulinternet.nl/?page=bicubic
http://dzone.com/snippets/cubic-interpolation
但我不知道如何使用此代码:/
根据这个简单的例子给4分:
float cubic_interpolate( float y0, float y1, float y2, float y3, float mu ) {
float a0, a1, a2, a3, mu2;
mu2 = mu*mu;
a0 = y3 - y2 - y0 + y1; //p
a1 = y0 - y1 - a0;
a2 = y2 - y0;
a3 = y1;
return ( a0*mu*mu2 + a1*mu2 + a2*mu + a3 );
}
第一个我不明白的是参数。我有 4 个点和一个介于 0 和 1 之间的值。那么我的 return 值是多少?或者更好的是什么是 mu? y0 ... y3 只是点的 y 值还是像 y0[0] 是 x 和 y0[1] 是 y 这样的点?我需要的是一种算法,它有一些点和一个 x 值作为参数,return 值应该是 y 值。
类似的东西:
function calculateCubic( points ){
var pointsToDraw = [];
getValue(p1,p2,p3,p4,xCoordinate){
var yCoordinate;
yCoordinate = ...
...
return yCoordinate;
}
for(var i = 0; i<p.length-3;i++){
var stepLen = ( p[i+1][0] - p[i][0] ) / 100;
for( var s = p[i][0]; s <= p[i+1][0] ;s += stepLen ){
pointsToDraw[pointsToDraw.length] = getValue(p[i],p[i+1],p[i+2],p[i+3],p[i][0]);
}
}
return pointsToDraw;
}
任何人都可以帮助我理解代码片段并将它们用于我的问题吗?
多谢指教!
看起来代码对一组数据点进行了三次插值,返回的是 Catmull-Rom 样条。
你最好使用贝塞尔样条曲线,在我看来它更容易实现。
mu 是给出曲线位置的参数。要在曲线上绘制一组 10 个点,请使用相同的 y0、y1、y2、y3 值和 mu 0、0.1、0.2、0.3、... 1.0 的值。
要了解此处的 y 值,请查看将 mu=0 和 mu=1 放入函数时会发生什么。 mu=0 函数 returns y1。当 mu=1 时,函数 returns y2。我们看到这种样条曲线穿过中间的两个控制点。
正如 Mark 所说,这不是最容易使用的样条曲线。你最好使用贝塞尔样条曲线。他们的一个非常好的页面是 http://pomax.github.io/bezierinfo/. There is also a bezierCurveTo
function in the javascript canvas which makes them easy to use API doc.
您发布的链接中的示例代码都是从 4 个点或从 2 个点和 2 个导数的三次插值。
'mu' 是您要计算 y 值的参数。输入的y0、y1、y2、y3是4个输入点的y坐标。您可以通过将 x0、x1、x2 和 x3 传递给函数来执行相同的操作以评估参数 'mu' 处的 x 值。
你说你想要一个将 x 值作为参数输入并返回 y 值作为输出的函数。这只有在您以显式形式表示曲线时才有可能,即 y=f(x)。但是,显式形式无法表示具有多个 y 值和相同 x 值的曲线。因此,它们通常不是表示曲线的好方法。参数形式是表示曲线的更好方法。例如,2D 曲线 C(t) 表示为 C(t) = (x(t), y(t)) 或 3D 曲线可以表示为 C(t)=(x(t), y( t), z(t)).将一个完整的圆表示为 (x(t), y(t))=(rcos(t),rsin(t)) 是参数形式的一个很好的例子。
如果要绘制连接一系列数据点的平滑曲线,最简单的方法是实现 Catmull Rom 样条或 Overhauser 样条。它们都是三次 Hermite 曲线的特殊形式。阅读有关三次 Hermite 曲线 here 的维基百科页面并转到同一页面中的 Catmull Rom 样条部分,您将能够知道如何创建插值数据点的 Catmull Rom 样条以及如何评估它以获得(x, y) 值在 canvas.
中绘制样条曲线