贝塞尔曲线的长度始终相同
我正在 HTML5 画布上开发游戏。
我想要的是在两点之间绘制一条S形三次贝塞尔曲线,但我正在寻找一种方法来计算控制点的坐标,以便无论这些点有多近,曲线本身总是相同的长度,直到它到达曲线变成直线的点。
I'm working on a game in HTML5 canvas.
I want is draw an S-shaped cubic bezier curve between two points, but I'm looking for a way to calculate the coordinates of the control points so that the curve itself is always the same length no matter how close those points are, until it reaches the point where the curve becomes a straight line.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是可以数值求解的。我假设你有一个带有 4 个控制点的三次贝塞尔曲线。
在每一步中,您都有第一个 (P0) 和最后一个 (P3) 点,并且您想要计算 P1 和 P2 以使总长度恒定。
添加此约束会删除一个自由度,因此我们还剩下 1 个自由度(从 4 开始,确定终点 (-2),恒定长度是另一个 -1)。所以你需要对此做出决定。
贝塞尔曲线是定义在 0 和 1 之间的多项式,您需要对元素总和 (2d?) 的平方根进行积分。对于三次贝塞尔曲线,这意味着 6 次多项式的 sqrt,wolfram 不知道如何求解。但是,如果您知道所有其他控制点(或已知对某些其他约束的依赖),您可以保存该约束的预先计算值的表。
This is solvable numerically. I assume you have a cubic bezier with 4 control points.
at each step you have the first (P0) and last (P3) points, and you want to calculate P1 and P2 such that the total length is constant.
Adding this constraint removes one degree of freedom so we have 1 left (started with 4, determined the end points (-2) and the constant length is another -1). So you need to decide about that.
The bezier curve is a polynomial defined between 0 and 1, you need to integrate on the square root of the sum of elements (2d?). for a cubic bezier, this means a sqrt of a 6 degree polynomial, which wolfram doesn't know how to solve. But if you have all your other control points known (or known up to a dependency on some other constraint) you can have a save table of precalculated values for that constraint.
曲线真的有必要是贝塞尔曲线吗? 拟合两个总长度恒定的圆弧要容易得多。而且你总是会得到一个S形。
拟合两个圆弧:
让 D 为端点之间的欧氏距离。令 C 为我们想要的恒定长度。我得到了以下 b 表达式(在图像中绘制):
我还没有检查它是否正确,所以如果有人得到不同的结果,请发表评论。
编辑:您也应该考虑我在求解方程时获得的负解,并检查哪一个是正确的。
Is it really necessary that the curve is a bezier curve? Fitting two circular arcs whose total length is constant is much easier. And you will always get an S-shape.
Fitting of two circular arcs:
Let D be the euclidean distance between the endpoints. Let C be the constant length that we want. I got the following expression for b (drawn in the image):
I haven't checked if it is correct so if someone gets something different, leave a comment.
EDIT: You should consider the negative solution too that I obtain when solving the equation and check which one is correct.
以下是 SVG 中的一个工作示例,接近需要更正:
http://phrogz.net/svg/constant-length-bezier.xhtml
我通过实验确定,当端点彼此重叠时,句柄应该是
所需长度 × cos(30°)
远离手柄; (当然)当端点处于最大距离时,手柄应该彼此叠置。绘制所有理想点看起来有点像一个椭圆:
">
这是相关的 JavaScript 代码:
Here's a working example in SVG that's close to correct:
http://phrogz.net/svg/constant-length-bezier.xhtml
I experimentally determined that when the endpoints are on top of one another the handles should be
desiredLength × cos(30°)
away from the handles; and (of course) when the end points are at their greatest distance the handles should be on top of one another. Plotting all ideal points looks sort of like an ellipse:
The blue line is the actual ideal equation, while the red line above is an ellipse approximating the ideal. Using the equation for the ellipse (as my example above does) allows the line to get about 9% too long in the middle.
Here's the relevant JavaScript code: