贝塞尔曲线弧长
Bezier curve arc lengths
我有一些代码可以计算贝塞尔曲线的长度。我正在尝试为它编写单元测试。但除了微不足道的情况(直线贝塞尔曲线)之外,我不知道长度的任何实际正确值。我上网查了,没找到。
有人知道这个信息吗?我正在寻找 link 到 table 的几行,其中包含四个贝塞尔曲线控制点,然后是一个长度,或者可能在计算长度的绘图程序中创建几个贝塞尔曲线(我'我试过使用 blender 和 inkscape 来获取这些信息,但它们非常复杂)。
解决方案。 从 here 下载 pomax 的 bezier javascript 代码,然后在网络浏览器中打开此 html:
<html>
<head>
<script src="bezier.js"></script>
</head>
<body>
<script>
curve = new Bezier([4.0, 0.0, 4.0,
4.0, 0.0, 12.0,
16.0, 0.0, 12.0,
16.0, 0.0, 4.0]);
document.write(curve.length());
</script>
</body>
</html>
您可以通过摆弄此页面上的 js 小部件来获取一些值
http://pomax.github.io/bezierinfo/#arclengthapprox
您可以尝试以下方法对您的代码进行单元测试:
1) 使用De Casteljau算法将贝塞尔曲线拆分为多条贝塞尔曲线
2) 计算每条贝塞尔曲线的弧长,然后计算它们的总和。
3) 计算原始贝塞尔曲线的弧长。
4) 比较第 2 步和第 3 步的结果。如果您的代码正确,它们应该只有很小的数字误差。
另一种验证弧长的方法是检查它是否始终在下面计算的两个值之间:
1) 从贝塞尔曲线中采样一些点(比如说 100 个)并根据采样点计算多边形的长度。该值将始终小于曲线的实际弧长。
2) 计算控制多边形的长度。这将始终大于曲线的实际弧长。
如果您想要 实际 弧长进行测试,请实施 https://github.com/Pomax/bezierjs/blob/gh-pages/lib/bezier.js#L602-604 - this will get you arbitrarily accurate numbers based on Legendre-Gauss quadrature 评估(您不必了解它是如何工作的,尽管视频 link 向您展示了它实际上非常简单。因此,实现它真的很容易)。
另一种选择是依赖类似 wolframalpha.com or Mathematica (which is free if you own a Raspberri PI 的东西):设置一条随机曲线,并让他们计算长度 "properly",然后在单元测试中使用该结果作为参考值。
意识到这是一个老问题,但另一种解决方案是使用 SVG 路径元素和 getTotalLength
方法。不需要库或复杂的方程式,让浏览器完成繁重的工作。
最简单的形式:
var a = {x: 0, y: 0}, // from
b = {x: 4, y: 4}, // to
c1 = {x: 2, y: 0}, // curve 1
c2 = {x: 2, y: 4}, // curve 2
// output the curve in SVG bezier syntax
svgBezier = `M${a.x} ${a.y} C ${c1.x} ${c1.y}, ${c2.x} ${c2.y}, ${b.x} ${b.y}`,
// create a new <path> element
path = document.createElementNS("http://www.w3.org/2000/svg", "path");
// add the curve
path.setAttribute('d', svgBezier);
// get the length using browser power
console.log(path.getTotalLength()); // 5.981128692626953
注意:以上 returns 在 chrome 和 safari 中的可靠结果.. firefox 开箱即用似乎不太可靠
我有一些代码可以计算贝塞尔曲线的长度。我正在尝试为它编写单元测试。但除了微不足道的情况(直线贝塞尔曲线)之外,我不知道长度的任何实际正确值。我上网查了,没找到。
有人知道这个信息吗?我正在寻找 link 到 table 的几行,其中包含四个贝塞尔曲线控制点,然后是一个长度,或者可能在计算长度的绘图程序中创建几个贝塞尔曲线(我'我试过使用 blender 和 inkscape 来获取这些信息,但它们非常复杂)。
解决方案。 从 here 下载 pomax 的 bezier javascript 代码,然后在网络浏览器中打开此 html:
<html>
<head>
<script src="bezier.js"></script>
</head>
<body>
<script>
curve = new Bezier([4.0, 0.0, 4.0,
4.0, 0.0, 12.0,
16.0, 0.0, 12.0,
16.0, 0.0, 4.0]);
document.write(curve.length());
</script>
</body>
</html>
您可以通过摆弄此页面上的 js 小部件来获取一些值 http://pomax.github.io/bezierinfo/#arclengthapprox
您可以尝试以下方法对您的代码进行单元测试:
1) 使用De Casteljau算法将贝塞尔曲线拆分为多条贝塞尔曲线
2) 计算每条贝塞尔曲线的弧长,然后计算它们的总和。
3) 计算原始贝塞尔曲线的弧长。
4) 比较第 2 步和第 3 步的结果。如果您的代码正确,它们应该只有很小的数字误差。
另一种验证弧长的方法是检查它是否始终在下面计算的两个值之间:
1) 从贝塞尔曲线中采样一些点(比如说 100 个)并根据采样点计算多边形的长度。该值将始终小于曲线的实际弧长。
2) 计算控制多边形的长度。这将始终大于曲线的实际弧长。
如果您想要 实际 弧长进行测试,请实施 https://github.com/Pomax/bezierjs/blob/gh-pages/lib/bezier.js#L602-604 - this will get you arbitrarily accurate numbers based on Legendre-Gauss quadrature 评估(您不必了解它是如何工作的,尽管视频 link 向您展示了它实际上非常简单。因此,实现它真的很容易)。
另一种选择是依赖类似 wolframalpha.com or Mathematica (which is free if you own a Raspberri PI 的东西):设置一条随机曲线,并让他们计算长度 "properly",然后在单元测试中使用该结果作为参考值。
意识到这是一个老问题,但另一种解决方案是使用 SVG 路径元素和 getTotalLength
方法。不需要库或复杂的方程式,让浏览器完成繁重的工作。
最简单的形式:
var a = {x: 0, y: 0}, // from
b = {x: 4, y: 4}, // to
c1 = {x: 2, y: 0}, // curve 1
c2 = {x: 2, y: 4}, // curve 2
// output the curve in SVG bezier syntax
svgBezier = `M${a.x} ${a.y} C ${c1.x} ${c1.y}, ${c2.x} ${c2.y}, ${b.x} ${b.y}`,
// create a new <path> element
path = document.createElementNS("http://www.w3.org/2000/svg", "path");
// add the curve
path.setAttribute('d', svgBezier);
// get the length using browser power
console.log(path.getTotalLength()); // 5.981128692626953
注意:以上 returns 在 chrome 和 safari 中的可靠结果.. firefox 开箱即用似乎不太可靠