用SDF畫(huà)貝塞爾曲線
GLSL教程5 - 2D SDF 操作和更多 2D 形狀點(diǎn)集/折線轉(zhuǎn)貝塞爾曲線
c++曲線擬合:貝塞爾曲線的控制點(diǎn)計(jì)算
如何生成光滑曲線?
Draw a Smooth Curve through a Set of 2D Points with Bezier Primitives
cflw_cpp/cflw代碼庫(kù)/cflw圖形_d2d助手.cpp
How to draw a smooth curve through a set of 2D points with Bezier methods?
bw2009/bwchart/bezier.cpp/GetCurveControlPoints
求高手解答 貝塞爾曲線問(wèn)題
①在動(dòng)畫(huà)控制中,一般使用三次貝塞爾曲線控制動(dòng)畫(huà)的“完成度”而不是“運(yùn)動(dòng)速度”,我相信樓主問(wèn)的也是用貝塞爾曲線控制動(dòng)畫(huà)“完成度”的問(wèn)題;

上圖是我做貝塞爾曲線編輯器。在一般的動(dòng)畫(huà)完成度編輯器中,x軸代表的是時(shí)間完成度,y軸代表動(dòng)畫(huà)完成度,x和y都在[0, 1]區(qū)間內(nèi)。當(dāng)x=1時(shí),y=1,y值代表的并不是“運(yùn)動(dòng)速度”。
②貝塞爾曲線中除了有已知的4個(gè)坐標(biāo)點(diǎn),還有3個(gè)可變參數(shù): t,x,y。其中t代表曲線的完成度(1%-100%),t對(duì)應(yīng)一個(gè)或者多個(gè)(x, y)坐標(biāo)點(diǎn)(因?yàn)?個(gè)已知坐標(biāo)點(diǎn)被控制在了一定區(qū)間內(nèi),所以貝塞爾曲線編輯器中t僅僅對(duì)應(yīng)一個(gè)(x, y)坐標(biāo));
③在已知t的情況下求解x和y是很容易的,但是已知x求y是非常困難的;
④正面去求值很困難,那就需要換一種方式去近似地去求值了(后面附代碼)。
**值得一提的是,Cocos2d-x中有貝塞爾曲線控制動(dòng)畫(huà)完成度的類,但實(shí)際上這個(gè)功能的實(shí)現(xiàn)卻是錯(cuò)誤的。**
**在CCTweenFunction.cpp中的bezieratFunction中可以看到在求解動(dòng)作完成度y時(shí)錯(cuò)誤地把x當(dāng)做了t。**
**所有x坐標(biāo)值都完全不參與計(jì)算過(guò)程**。
但由于在這種情況下t和y是正相關(guān)的,和x也是正相關(guān)的,所以也很難看出來(lái)動(dòng)畫(huà)有什么問(wèn)題
兩個(gè)解決方案
**1.使用CCActionEase.cpp的EaseBezierAction類糊弄過(guò)去;**
**2.自己求解貝塞爾曲線來(lái)控制動(dòng)畫(huà)的完成度**:首先需要采樣,假設(shè)采樣步長(zhǎng)是0.1,那么t = 0.1、0.2、0.3… 的條件下求解x和y的值,設(shè)為x1,y1,x2,y2,x3,y3…;然后進(jìn)行線性插值,已知目前的時(shí)間完成度x,可以求解出x所在的區(qū)間[xn, xn+1],y的值就在[yn, yn+1]之間,線性插值就可以得到近似結(jié)果。Lua版本的代碼如附件,只有求解貝塞爾曲線的部分,具體的動(dòng)畫(huà)控制需要再編碼完成。
[BezierCurve.zip](https://forum.cocos.org/uploads/default/original/2X/f/f23340efec3019edf20b644d121c06370634dd6a.zip) (1.2 KB)
- 在線調(diào)試貝塞爾曲線
cubic貝塞爾_cubic-bezier
cubic貝塞爾公式_desmos.com
任意貝塞爾曲線
三階貝塞爾曲線,控制點(diǎn)水平坐標(biāo)等分,且Y值和對(duì)應(yīng)的固定點(diǎn)一致時(shí)
Pbezier=P0?(1?t)3+3P1?(1?t)2?t+3P2?(1?t)?t2+P3?t3 //(t2 t3是t的2次和3次的意思)
假如 四個(gè)點(diǎn)分別是(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函數(shù)的形式
參考:在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āng)d= 1/3,x = t;
3?(1?t)?t2+t3 = 3t2 - 2t3
得證
-
smoothstep在變速曲線里的應(yīng)用
曲線變速.jpeg
公式調(diào)試網(wǎng)站:
https://www.desmos.com/calculator/sqppsdisl8?lang=zh-CN
f(x)為smoothstep函數(shù)
Q(x) 為變速進(jìn)度函數(shù)。X軸為播放變速后視頻的時(shí)間,Y軸表示變速進(jìn)度;
Z(x) 為初始速度為0.1,結(jié)束速度為0.9的瞬時(shí)速度函數(shù)。 X軸為播放變速后視頻的時(shí)間,Y軸表示此時(shí)刻的瞬時(shí)速度;
F(x) 為Z(x)函數(shù)的積分,表示當(dāng)前播放的長(zhǎng)度。 X軸為播放變速后視頻的時(shí)間,Y軸表示此時(shí)刻播到了原視頻的第幾秒;
R為定積分的減法形式。表示當(dāng)前時(shí)間段內(nèi)播放了多少秒
上面的網(wǎng)站也可以直接畫(huà)控制點(diǎn)。如把以下控制點(diǎn)直接粘貼,就可以直觀看出是怎樣的一系列貝塞爾曲線:
(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)
