@Craige_Hales和@mitulshah ,
我对贝塞尔曲线的知识和经验有限。 我已经看到它们在起草(建筑和景观)设计和服装设计中的实用性。 当然,数学基础对我来说总是很有趣。我在网上查了一下,发现@mitulshah求Excel的Bezier spline,B-spline,算法是比较常见的。 一个链接Excel平滑算法问题包括指向 zip 文件的链接: http://xlrotor.com/Smooth_curve_bezier_example_file.zip此 zip 包含一个 2002 .xls 贝塞尔曲线示例,其中嵌入了自动化例程,可从 Excel 平滑曲线中获取像素并在曲线上插入点。它不是“精确”的,并且使用了一种从曲线上抓取 4 个像素的技术。 端点在第一个插值点和最后一个插值点中使用两次。
我在 Craige 发表关于 GraphBuilder Line 元素选项以使其成为曲线的帖子后发现了一个 JMP,即用于此平台的样条必须使用不同的算法,因为端点斜率与 Excel 的非常相似。我启动了一个脚本,通过提取 GB 图的像素来执行一些 DSP(数字信号处理)。 然后我找到上面列出的网络链接,并决定只使用 Excel 电子表格中的插值点并将其与 GB 线(曲线)叠加。 下面的第一个屏幕截图描述了 Excel 工作表,其中包含带有贝塞尔样条曲线和插值点的 Excel 图形,这些点作为自旋 B 点添加到 JMP 表中。第二张图片显示了 JMP GB 线(曲线),其中覆盖了 Excel 插值点。
Excel Interpolated Points > Spin B in JMP tableExcel 插值点 > JMP 表中的自旋 B
JMP Line(curve) spline overlaid with Excel interpolationsJMP 线(曲线)样条覆盖 Excel 插值
您会注意到插值与上尾部的 JMP 线(曲线)略有偏移,这可能是由于插值算法、Excel 和 JMP 曲线的差异或两者的组合。 请注意,相同的 4 个点略高于 Excel 图表中的曲线。
所以,我的结论是 JMP GB 线(曲线)样条与 Excel 贝塞尔曲线非常相似。我的兴趣不高,但如果我感到无聊,我可能会完成我的 DSP 脚本以“获取”线(曲线)点。早期版本的 JMP 用于报告保存的 .jrn 文件中的曲线点,现在 .jrn 文件中仅包含对隐藏函数的引用。
现在,如果我就这个问题进行咨询,我的第一组问题是:
- 这些数据(4分)从何而来,目标是什么?
- 样条曲线,如直线和多项式,可用于创建校准曲线(用于插值的曲线)代替复杂的函数关系。 但是,为了准确起见,如果要根据曲线计算插值,建议定期数据间隔和重复。 由于 X 值是不规则间隔的,我想知道是否存在影响 X 和 Y 的第三个(或更多)变量。 例如,两者都是来自每日或每周测试读数的读数。
- 是否存在以 X 和 Y 的关系为基础的基本第一原则,例如:剂量反应;细胞生长;污染-腐蚀等
- 为什么积分这么少? 复制子的成本是多少?
根据我的经验,如果存在基本的非线性关系,那么获取数据和拟合关系以估计参数(学习曲线、退化曲线)等的努力通常是值得的。如所提供的优秀信息所示Craige Hales,控制点(数量和位置)、结点和端点的微小差异可以使样条曲线的曲率(曲线上的点)产生很大差异,尤其是“x”中的大间隙。我的预感是 Excel 故意不发布点或曲线样条的公式,因此人们不会像拟合模型一样使用它进行估计。注意 X 和复制的“接近”值,插值的风险要小得多。
样条曲线在开始和结束时选择斜率,这对于 JMP 和 Excel 而言似乎并不相同。 样条在每对点之间使用不同的三次方,可以平滑地连接大量点,匹配斜率和曲率。 如果只有四个点,则将立方体拟合到四个点并使用公式进行插值可能有意义。
也许我们会得到统计学家的答案。
Graph Builder can do it. So can Fit Y by X.Graph Builder 可以做到。 所以可以用 X 拟合 Y。
对于这里的混乱,我深表歉意。
数据:

在 JMP 中,我用 X 拟合 Y


如果我在Excel中输入相同的数据

我明白了

请注意,在 JMP 绿线中,左下方(X 值 2-3 之间)的曲线中有一点振荡/扭结,而在 Excel 中情况并非如此。
我的最终目标是从该行内插值,因此如果 Excel 和 JMP 给出两条不同的线,那么我最终会得到不同的内插值。
这就是我想要做的
使用平滑曲线功能复制 Excel 的散点图。
如果我使用具有灵活脊柱的 JMP fit Y by X,我得到的曲线与 Excel 使用散点图 + 平滑线生成的曲线不同。 我相信 Excel 正在使用贝塞尔曲线拟合。
数据点:
自旋 | × |是
一个| 2.41 | 846.8692
一个| 0.93 | 77.043
一个| 1.37 | 155.2193
一个 | 1.96 | 390.4639

我不想使用灵活的样条曲线绘制这条线,但我想强制使用贝塞尔曲线。 我希望这是有道理的。
谢谢
嗨克雷奇,
我试图理解 path () 函数和移动点、控制点、贝塞尔曲线点。
从我掌握的数据中我有这四点
点=
[ 0.93 77.04 1,
1.37 155.22 0,
1.96 390.46 0,
2.41 846.87 3];
当我把它放在路径函数中时,我在点 1 和点 4 之间得到一条线,但它不通过点 2 和点 3。 我错过了什么吗?
谢谢。
多个答案,取决于您需要做什么。 这里有一些。
对于二维图形,您可以使用路径函数。 您无法通过搜索 Bezier 找到它,因为脚本索引拼写为 Bézier。 请尝试搜索 zier。@XanGregg @sheila_loring
此示例使用可拖动手柄扩展了脚本索引示例。
// initial data; points 3 and 5 are not initially constrained about point 4
points = [
10 10 1,// move-to
30 70 0,// control point
40 10 0,// control point
50 40 3,// bezier
60 60 0,// control point
70 20 0,// control point
90 10 3 // bezier
];
// moving a square handle will call this function to
// copy the handle coordinates to the matrix
setpoint = Function( {index, x, y}, // parameters
{angle, distance}, // local variables
// copy to the matrix
points[index, 1] = x;
points[index, 2] = y;
// 3 and 5 are constrained about 4, comment out to see why...
// if the angles don't match, it isn't smooth
If( index == 3 | index == 5,
other = If( index == 3, 5, 3 ); // if I'm 3, he must be 5, etc
// trig in radians, 2*pi is 360
// atan does all 4 quadrants with 2 arguments
angle = ATan( points[index, 2] - points[4, 2], points[index, 1] - points[4, 1] );
// maintain other's distance
distance = Sqrt( (points[other, 2] - points[4, 2]) ^ 2 + (points[other, 1] - points[4, 1]) ^ 2 );
// fix other's angle to match my angle, but opposite me
points[other, 1] = points[4, 1] + distance * Cos( angle + Pi() );
points[other, 2] = points[4, 2] + distance * Sin( angle + Pi() );
);
// redraw
gb << inval;
);
New Window( "Example",
gb = Graph Box(
Fill Color( "blue" );
// there is no good shortcut for creating handles; the JSL holds the instances
Handle( points[1, 1], points[1, 2], setpoint( 1, x, y ) );
Handle( points[2, 1], points[2, 2], setpoint( 2, x, y ) );
Handle( points[3, 1], points[3, 2], setpoint( 3, x, y ) );
Handle( points[4, 1], points[4, 2], setpoint( 4, x, y ) );
Handle( points[5, 1], points[5, 2], setpoint( 5, x, y ) );
Handle( points[6, 1], points[6, 2], setpoint( 6, x, y ) );
Handle( points[7, 1], points[7, 2], setpoint( 7, x, y ) );
// construction lines
Pen Color( "red" );
Line( {points[1, 1], points[1, 2]}, {points[2, 1], points[2, 2]} );
Line( {points[3, 1], points[3, 2]}, {points[4, 1], points[4, 2]} );
Line( {points[4, 1], points[4, 2]}, {points[5, 1], points[5, 2]} );
Line( {points[6, 1], points[6, 2]}, {points[7, 1], points[7, 2]} );
// the bezier
Pen Color( "black" );
Path( points );
)
);我意识到我还应该限制移动点 4 来拖动点 3 和 5。 (未完成,应该很容易。)
Bezier control points贝塞尔控制点
也许你需要一个样条曲线。 我不确定脚本索引中样条曲线、p 样条曲线、b 样条曲线之间的区别是什么。 我用样条HeatColor vs Spline vs Interpolate使这条曲线
spline coef, spline eval样条系数,样条评估
在 JMP 的 3D OpenGL 支持中也支持贝塞尔曲线: https://www.jmp.com/support/help/14-2/bezier-curves.shtml这可能有助于绘制表面。 一个糟糕的例子隐藏在傅里叶变换视频
很棒的帖子@Duane_Hayes了解三次样条
我一路上遇到的事情: https://www.tinaja.com/glib/bezconn.pdf