其他分享
首页 > 其他分享> > [笔记] Photoshop钢笔工具原理: Bézier曲线

[笔记] Photoshop钢笔工具原理: Bézier曲线

作者:互联网

Photoshop中有一种钢笔工具,只需确定几个点,即可画出一条看起来很自然的曲线段
image
他需要四个点来确定一条曲线段:

它的原理十分简单、且易于拓展到任意多个控制点、应用也十分广泛

插值

直线段的表示

确定一条线段的一种方式是使用两个点\(\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