用SDF画贝塞尔曲线
GLSL教程5 - 2D SDF 操作和更多 2D 形状点集/折线转贝塞尔曲线
c++曲线拟合:贝塞尔曲线的控制点计算
如何生成光滑曲线?
Draw a Smooth Curve through a Set of 2D Points with Bezier Primitives
cflw_cpp/cflw代码库/cflw图形_d2d助手.cpp
How to draw a smooth curve through a set of 2D points with Bezier methods?
bw2009/bwchart/bezier.cpp/GetCurveControlPoints
求高手解答 贝塞尔曲线问题
①在动画控制中,一般使用三次贝塞尔曲线控制动画的“完成度”而不是“运动速度”,我相信楼主问的也是用贝塞尔曲线控制动画“完成度”的问题;
上图是我做贝塞尔曲线编辑器。在一般的动画完成度编辑器中,x轴代表的是时间完成度,y轴代表动画完成度,x和y都在[0, 1]区间内。当x=1时,y=1,y值代表的并不是“运动速度”。
②贝塞尔曲线中除了有已知的4个坐标点,还有3个可变参数: t,x,y。其中t代表曲线的完成度(1%-100%),t对应一个或者多个(x, y)坐标点(因为4个已知坐标点被控制在了一定区间内,所以贝塞尔曲线编辑器中t仅仅对应一个(x, y)坐标);
③在已知t的情况下求解x和y是很容易的,但是已知x求y是非常困难的;
④正面去求值很困难,那就需要换一种方式去近似地去求值了(后面附代码)。
**值得一提的是,Cocos2d-x中有贝塞尔曲线控制动画完成度的类,但实际上这个功能的实现却是错误的。**
**在CCTweenFunction.cpp中的bezieratFunction中可以看到在求解动作完成度y时错误地把x当做了t。**
**所有x坐标值都完全不参与计算过程**。
但由于在这种情况下t和y是正相关的,和x也是正相关的,所以也很难看出来动画有什么问题
两个解决方案
**1.使用CCActionEase.cpp的EaseBezierAction类糊弄过去;**
**2.自己求解贝塞尔曲线来控制动画的完成度**:首先需要采样,假设采样步长是0.1,那么t = 0.1、0.2、0.3… 的条件下求解x和y的值,设为x1,y1,x2,y2,x3,y3…;然后进行线性插值,已知目前的时间完成度x,可以求解出x所在的区间[xn, xn+1],y的值就在[yn, yn+1]之间,线性插值就可以得到近似结果。Lua版本的代码如附件,只有求解贝塞尔曲线的部分,具体的动画控制需要再编码完成。
[BezierCurve.zip](https://forum.cocos.org/uploads/default/original/2X/f/f23340efec3019edf20b644d121c06370634dd6a.zip) (1.2 KB)
三阶贝塞尔曲线,控制点水平坐标等分,且Y值和对应的固定点一致时
Pbezier=P0⋅(1−t)3+3P1⋅(1−t)2⋅t+3P2⋅(1−t)⋅t2+P3⋅t3 //(t2 t3是t的2次和3次的意思)
假如 四个点分别是(0.0, 1.0), (d, 1.0), (1.0 - d, 0.0),和(1.0, 0.0) =>
Pbezier=((3t−9t2+6t3)⋅d+3t2−2t3,1−3t2+2t3)
- 贝塞尔曲线可以拟合到smoothstep函数的形式
参考:在Unity的UI中绘制等宽的贝赛尔曲线
证明:
[https://www.desmos.com/calculator/fxgwaxa0l7?lang=zh-CN](https://www.desmos.com/calculator/fxgwaxa0l7?lang=zh-CN)
[https://www.desmos.com/calculator/wwwz88ko1r?lang=zh-CN](https://www.desmos.com/calculator/wwwz88ko1r?lang=zh-CN)
Pbezier=P0⋅(1−t)3+3P1⋅(1−t)2⋅t+3P2⋅(1−t)⋅t2+P3⋅t3 //(t2 t3是t的2次和3次的意思)
(0.0,0.0), (d, 0.0), (1.0 - d, 1.0),和(1.0, 1.0)
3d⋅(1−t)2⋅t + 3(1.0 - d)⋅(1−t)⋅t2 + t3
3dt-6dt2 + 3dt3 + 3(1.0 - d)t2 - 3(1.0 - d)t3 + t3
3d-3+3d+1 6d-2 t3
-6d +3-3d -9d +3 t2
3dt
当d= 1/3,x = t;
3⋅(1−t)⋅t2+t3 = 3t2 - 2t3
得证
-
smoothstep在变速曲线里的应用
曲线变速.jpeg
公式调试网站:
https://www.desmos.com/calculator/sqppsdisl8?lang=zh-CN
f(x)为smoothstep函数
Q(x) 为变速进度函数。X轴为播放变速后视频的时间,Y轴表示变速进度;
Z(x) 为初始速度为0.1,结束速度为0.9的瞬时速度函数。 X轴为播放变速后视频的时间,Y轴表示此时刻的瞬时速度;
F(x) 为Z(x)函数的积分,表示当前播放的长度。 X轴为播放变速后视频的时间,Y轴表示此时刻播到了原视频的第几秒;
R为定积分的减法形式。表示当前时间段内播放了多少秒
上面的网站也可以直接画控制点。如把以下控制点直接粘贴,就可以直观看出是怎样的一系列贝塞尔曲线:
(0.0000000000,0.1000000000)
(0.0000000000,0.1000000000)
(1.6572717167,0.1000000000)
(4.9718151501,7.0900000000)
(3.3145434334,7.0900000000)
(7.8372575211,7.0900000000)
(13.5681422632,0.6000000000)
(10.7026998922,0.6000000000)
(14.5202490657,0.6000000000)
(16.4244626706,0.5900000000)
(15.4723566895,0.5900000000)
(16.4244626706,0.5900000000)