如何在 C++ 中实现 Bézier 曲线?
我想实现贝塞尔曲线。 我应该如何创建二次曲线?
void printQuadCurve(float delta, Vector2f p0, Vector2f p1, Vector2f p2);
显然我们需要使用线性插值,但这是否存在于标准数学库中? 如果没有,我在哪里可以找到它?
我正在使用Linux。
I'd like to implement a Bézier curve. How should I go about creating a quadratic curve?
void printQuadCurve(float delta, Vector2f p0, Vector2f p1, Vector2f p2);
Clearly we'd need to use linear interpolation, but does this exist in the standard math library? If not, where can I find it?
I'm using Linux.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
最近我遇到了同样的问题,想自己实现。
来自维基百科的这张图片对我有帮助:
以下代码演示了如何计算二次贝塞尔曲线。
其中(x1|y1)、(x2|y2)和(x3|y3)为图像中的P0、P1和P2。 只是为了展示基本想法...
对于那些要求三次贝塞尔曲线的人,它只是模拟(也来自维基百科):
这个答案提供了代码。
Recently I ran across the same question and wanted to implemented it on my own.
This image from Wikipedia helped me:
The following code shows how to compute a quadratic bezier.
With (x1|y1), (x2|y2) and (x3|y3) being P0, P1 and P2 in the image. Just for showing the basic idea...
For the ones who ask for the cubic bezier, it just works analogue (also from Wikipedia):
This answer provides Code for it.
这是具有任意数量点的曲线的一般实现。
请注意,它使用堆内存作为临时数组,这并不是那么高效。 如果您只需要处理固定数量的点,您可以对 numPoints 值进行硬编码并使用堆栈内存。
当然,上面假设您有一个 vec2 结构和运算符,如下所示:
Here is a general implementation for a curve with any number of points.
Note that it uses heap memory for a temporary array which is not all that efficient. If you only need to deal with a fixed number of points you could hard-code the numPoints value and use stack memory instead.
Of course, the above assumes you have a vec2 structure and operators for it like this:
您可以选择 de Casteljau 方法(如上所述,递归地分割控制路径,直到使用线性插值到达该点)或 Bezier 方法(混合控制点)。
贝塞尔方法
适用于三次方和
二次方。
t 通常在 0-1 之间,但这不是必需的 - 事实上曲线延伸到无穷大。 P0、P1等为控制点。 曲线穿过两个端点,但通常不穿过其他点。
You have a choice between de Casteljau's method, which is to recursively split the control path until you arrive at the point using a linear interpolation, as explained above, or Bezier's method which is to blend the control points.
Bezier's method is
for cubics and
for quadratics.
t is usually on 0-1 but that's not an essential - in fact the curves extend to infinity. P0, P1, etc are the control points. The curve goes through the two end points but not usually through the other points.
您之前使用过 C# 库吗?
在 C++ 中,尚无可用的贝塞尔曲线标准库函数。 您当然可以自己动手(CodeProject 示例)或寻找数学图书馆。
这篇博文很好地解释了这个想法,但是是在 Actionscript 中。 翻译应该不是什么大问题。
Did you use a C# library earlier?
In C++, no standard library function for Bezier curves is available (yet). You can of course roll your own (CodeProject sample) or look for a math library.
This blogpost explains the idea nicely but in Actionscript. Translation should not be much of a problem.
使用给定控制点
(x1, y1),以给定行程百分比
、(t)
沿三次曲线获取单个点(x, y)
(x2, y2)
、(x3, y3)
和(x4, y4)
我扩展了 De Casteljau 的算法并重新排列方程以最小化指数:(t)
是 0 到 1 之间的十进制值(0 <= t <= 1)
,表示沿路径行驶的百分比曲线。x 和 y 的公式相同,您可以编写一个函数,该函数采用 4 个控制点的通用集合或将系数分组在一起:
对于二次函数,类似的方法得出:
To get an individual point
(x, y)
along a cubic curve at a given percent of travel(t)
, with given control points(x1, y1)
,(x2, y2)
,(x3, y3)
, and(x4, y4)
I expanded De Casteljau’s algorithm and rearranged the equation to minimize exponents:(t)
is a decimal value between 0 and 1(0 <= t <= 1)
that represents percent of travel along the curve.The formula is the same for x and y, and you can write a function that takes a generic set of 4 control points or group the coefficients together:
For quadratic functions, a similar approach yields:
如果您只想显示贝塞尔曲线,您可以使用类似 PolyBezier for Windows。
如果您想自己实现该例程,可以找到 线性插值代码遍布Intarnetz。
我相信 Boost 库对此有支持。 线性插值,而不是特指贝塞尔曲线。 不过,请不要引用我的观点。
If you just want to display a Bezier curve, you can use something like PolyBezier for Windows.
If you want to implement the routine yourself, you can find linear interpolation code all over the Intarnetz.
I believe the Boost libraries have support for this. Linear interpolation, not Beziers specifically. Don't quote me on this, however.
我基于此示例 https://stackoverflow.com/a/11435243/15484522 进行了实现,但对于任意数量路径点
其中 arr 是点数组 {x1, y1, x2, y2, x3, y3...xn, yn},size 是点的数量(小两倍)比数组大小),数量是输出点数。
为了获得最佳计算效果,您可以使用 2^n 数量和位移位:
I made an implementation based on this example https://stackoverflow.com/a/11435243/15484522 but for any amount of path points
Where arr is array of points {x1, y1, x2, y2, x3, y3... xn, yn}, size is amount of points (twice smaller than array size), and amount is number of output points.
For optimal calculations you can use 2^n amount and bit shift:
从版本 1.82 开始,Boost 支持 bezier_polynomial< /a> (实际上来自 1.78 版本,但在 1.82 中修复了一个 bug) 。
Starting from version 1.82 Boost supports bezier_polynomial (actually from version 1.78, but there were a bug fixed in 1.82).
此 github 上的实现展示了如何计算简单的三次贝塞尔曲线,“t”值的法线值和正切值范围为 0->1。
它是维基百科公式的直接转置。
This implementation on github shows how to calculate a simple cubic bezier, with normal and tangent values for values of 't' from 0->1.
It is a direct transposition of the formulas at wikipedia.