ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-01-16 17:02:50  阅读:300  来源: 互联网

标签:Photoshop p0 zier Vector2 linearInterpolate 钢笔 points vec var


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

  • 起始点(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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有