Equal Width Bezier Curve

在Unity的UI中绘制等宽的贝赛尔曲线

动机和贝塞尔曲线相关的背景知识 动机当然是要在UI上绘制一个贝塞尔曲线的形状了,想做的效果大概就和虚幻引擎蓝图连接节点的线差不多了。这里要绘制的是一种较为特殊的贝塞尔曲线,它的两个端点的切线是水平的,且拥有旋转对称的特性。 我们想要绘制的S形曲线是三阶的贝塞尔曲线。三阶贝塞尔曲线有四个控制点\(P_0, P_1, P_2, P_3\),对于一个从0到1的变量\(t\),贝塞尔曲线的做法是对这四个点按照顺序以\(t\)做插值生成三个新的点,然后对这三个点按照顺序以\(t\)做插值生成新的两个点,再对这两个点以t做插值生成最后的点,当t在0到1中变化时,这个点的轨迹就构成了贝塞尔曲线。贝塞尔曲线上的点可以用四个控制点和\(t\)来表示: $$ P_{bezier} = P_0 \cdot (1 - t)^3 + 3 P_1 \cdot (1 - t)^2 \cdot t + 3 P_2 \cdot (1 - t) \cdot t^2 + P_3 \cdot t^3 $$ 如果初始四个点分别是(0.0, 1.0), (d, 1.0), (1.0 - d, 0.0),和(1.0, 0.0)的话,也就是我们所要绘制的特殊的贝塞尔曲线,可以算出贝塞尔曲线的坐标为 $$ P_{bezier} = ((3 t - 9t ^ 2 + 6t^3) \cdot d + 3t^2 - 2t^3, 1 - 3t^2 + 2t^3) $$ 但是即使得到了贝塞尔曲线的参数方程,想要将其表达成\(f(x)\)的形式仍然是相当困难的。Alan Wolfe在他的博客中提到了一种一维贝塞尔曲线,也是一种贝塞尔曲线的特殊情况,四个控制点在水平方向上等距排开,这样子贝塞尔曲线的参数方程的水平分量就刚好是\(t\),它的竖直分量也就是我们需要的\(f(x)\)。唯一美中不足的是,能轻易得到\(f(x)\)的一维贝赛尔曲线,往往是一个“躺倒”的贝赛尔曲线,感官上看上去是横着的,Shadertoy上有相关的演示。但这种一维贝塞尔曲线又有一种特殊情况,也就是前两个控制点的竖直高度相等,后两个控制点的竖直高度也相等,这时这种特殊的一维贝塞尔曲线就是我们耳熟能详的smoothstep曲线了(数学真奇妙啊)。可惜smoothstep不能满足我们随意控制曲线形状的需求,只能另求他法。...

December 15, 2021 · zznewclear13
zznewclear13 技术美术 图形学 个人博客 technical art computer graphics