[笔记] Photoshop钢笔工具原理: Bézier曲线
作者:互联网
Photoshop中有一种钢笔工具,只需确定几个点,即可画出一条看起来很自然的曲线段
他需要四个点来确定一条曲线段:
- 起始点(start point)和结束点(end point)
- 两个控制点(control point)
它的原理十分简单、且易于拓展到任意多个控制点、应用也十分广泛
插值
直线段的表示
确定一条线段的一种方式是使用两个点\(\vec{p_0}\)和\(\vec{p_1}\)
\(\vec{r}(t) = \vec{p_0} + t \cdot (\vec{p_1}-\vec{p_0}) , \quad t \in [0,1]\)
其中\(\vec{r}=(x,y)\)为直线段的位矢
可以直观的理解为一点从\(\vec{p_0}\)出发,匀速移动到\(\vec{p_1}\),从式中可看出,在\(t=0\)时,\(\vec{r}(t)\)位于起点,\(t=1\)时,\(\vec{r}(t)\)位于终点
线性插值
这种在两点间均匀的插入中间值(匀速移动)的方式叫做线性插值
图形编程中,常这样编写线性插值
fun linearInterpolate(p0 :Vector2, p1 :Vector2, t :Float) :Vector2 {
var r = p0 + (p1-p0) * t
return r
}
注意到linearInterpolate
可以将两个点p0
,p1
变成了一个动点r
,如果递归的使用线性插值,就可以将任意有限个点变为一个动点,从而形成一条曲线,这便是Bézier曲线
Bézier曲线
贝塞尔曲线于1962,由法国工程师皮埃尔·贝塞尔(Pierre Bézier)所广泛发表
2阶Bézier曲线
假设有有序的三个点(start,mid,end)
,我们可以先用(start,mid)线性插值,生成一个动点q0
.再用mid,end)
生成一个动点q1
,最后,将q0
,q1
线性插值,生成一个动点r
,r
的轨迹便是Bézier曲线
fun linearInterpolate(p0 :Vector2, p1 :Vector2, t :Float) = p0 + (p1-p0) * t
fun Bezier2(start :Vector2, mid :Vector2, end :Vector2, t :Float) :Vector2 {
var q0 = linearInterpolate(start, mid, t)
var q1 = linearInterpolate(mid, end, t)
var r = linearInterpolate(q0, q1, t)
return r
}
n阶Bézier曲线
一种直观但相当低效的实现(未经验证)
class Vector2(var x:Float, var y:Float) {
operator fun plus(op :Vector2) :Vector2 = Vector2(x+op.x,y+op.y)
}
fun linearInterpolate(p0 :Vector2, p1 :Vector2, t :Float) = p0 + (p1-p0) * t
fun Bezier(points: List<Vector2>, t: Float) {
var current_points = points.toMutableList()
var new_points: MutableList<Vector2> = mutableListOf()
while (!current_points.isEmpty()) {
for(i in 0 until current_points.size-1) {
new_points.add( linearInterpolate(current_points[i],current_points[i+1], t) )
}
current_points.removeAt(0)
new_points.clear()
}
}
标签:Photoshop,p0,zier,Vector2,linearInterpolate,钢笔,points,vec,var 来源: https://www.cnblogs.com/winterreisender/p/15810264.html