天天看點

bezier曲線_貝塞爾曲線

首先,請感受下貝塞爾曲線之美。

二階

bezier曲線_貝塞爾曲線

七階

bezier曲線_貝塞爾曲線

十二階

bezier曲線_貝塞爾曲線

1993年的熱夏,深圳大學計算機系釋出了學生的畢業作品。當時有一公司老闆,無意中浏覽時,發現了一個能

分析股票的走向

的程式。他當即聯系到了作者,決定買下它。更多的是出于對編寫者才能的欣賞,他給了這個大學剛畢業還很迷茫的年輕人五萬元。編寫者非常激動。當時那可不是一筆小錢。

這個老闆或許連他自己都沒想到,自己的慷慨,卻促成了的将來的一位億萬富豪。

知乎視訊​www.zhihu.com

bezier曲線_貝塞爾曲線

股市大家一定都不陌生,它會定期釋出資料點。股市說白了,就是許多點坐落在橫軸時間上。

bezier曲線_貝塞爾曲線

進入今天的課題,我們要從一堆點中推算出一條線來。不過現在水準不夠,股市推不出來,可以先算點簡單的:

如果已知兩個點 (x, y)(a, b),可以求出直線式 y = k x + b,然後這條直線上的每一個點都可以算。

已知三個點(x, y) (a, b) (n, m),可以求出抛物線 y = a x^2 + b x + c,然後,抛物線上的每一個點,我們都可以算。

已知四個點,解四元三次方程,可能要花3分鐘得到一條曲線。

已知六個點,我們需要解六元五次方程,可能花上半小時。

股市有幾個點,一萬個?花一輩子都解不出來。

琢磨着有啥辦法可以簡單快速的,通過點坐标,導一條曲線。

bezier曲線_貝塞爾曲線

不要急着得到答案,我們先回歸本質。仔細想想點與線到底有什麼關聯。結合上述,有n個點要導n次方程式;是以,點的數量越多,線性越複雜。

bezier曲線_貝塞爾曲線

我們可以說點對線具有吸引力。點若聚集,吸引力會疊加,線會被吸引力大的地方拉扯過去。吸引力随着距離增加而減小:線離點越遠,被拉扯的幅度越小。

結合之前,同一平面内:點越密集的地方,線的變化越複雜;反之,點越稀疏的地方,線的變化越單一。現在假設,平面内有一條線,現有兩個點,兩個施加吸引力的機關,令其坐标為[0, 0]和[10, 0]。有兩個力,方向相反,是以這條線會被拉直。

bezier曲線_貝塞爾曲線

但是,若在[5, 5]的位置加入點,令其對這條線的吸引力與剩下兩點相等,則

bezier曲線_貝塞爾曲線

現在唯一的問題,就是我們不知道被拉扯了多少,它可能是這樣,也可能是這樣:

bezier曲線_貝塞爾曲線
bezier曲線_貝塞爾曲線

既然引入了力的概念,就不得不談運動。運動以時間來衡量。若以百分比量化時間,在t=0的時候,平面空白,在t=1的時候,線從一個端點完全運動到另外一個端點。

線都從t=0全部開始運動,并且在t=1結束運動。無論有幾個點,都是如此

bezier曲線_貝塞爾曲線
bezier曲線_貝塞爾曲線
bezier曲線_貝塞爾曲線

無論線的端點是否運動,也是如此

bezier曲線_貝塞爾曲線
bezier曲線_貝塞爾曲線

時間被分為等分後,在每一刻鐘,運動點都有一個獨立位置。是以,若知道兩個端點的坐标,知道此刻的t,我們就可以求出運動點的位置。換句話說,知道端點坐标,就可以算此刻的線段長度,而運動點,剛好處于長度的百分之t的位置。以下圖為例。

bezier曲線_貝塞爾曲線
bezier曲線_貝塞爾曲線

你現在肯定很頭昏,别有壓力,貝塞爾曲線是大學内容,有中數以上的水準才能掌握。堅持看到這裡,肯定已經了解點與線之間的互動,為什麼要求貝塞爾曲線以及背後的實體思考。這比單純背公式要好得多。

進入計算之前,我得先講講階乘 (reduce) 和帕斯卡三角 (Pascal’s Triangle)

常數後加個驚歎号,表示階乘:從原數一直乘到1

bezier曲線_貝塞爾曲線

帕斯卡三角用來解完全n方,每一行表示系數。

bezier曲線_貝塞爾曲線
bezier曲線_貝塞爾曲線

問:(a+b)^23化簡後,a^7b^16項的系數是什麼?

有了帕斯卡三角形,就可以算這類問題。

帕斯卡三角形中的每一個數,靠行數和列數來定位。計算機中一般從0開始計,而不是1。是以第一行第一列為(0, 0)

bezier曲線_貝塞爾曲線

知道行和列之後,可以通過公式求該系數。

求(a + b)的完全n方,我們隻需要得到帕斯卡三角形中的第n+1行,因為帕斯卡三角形第n行有n個數,可以将列數從0到n-1帶入計算,得到全部系數。

bezier曲線_貝塞爾曲線

貝塞爾曲線,若有3個點,要把3個點化為2個點,然後把兩個點化為1個點,則最後這個點的軌迹就是所求曲線。

以此類推,若一開始有4個點,就要化為3個點,再化為2個點,最後化為1個點。

總之就是要一直化,直到隻剩一個點。

是以,

bezier曲線_貝塞爾曲線

文章到此結束,有興趣繪高階曲線的同學,繼續往下看。

Python 3, Matplotlib

Weilory/Matplotlib-BezierCurve-Animator​github.com

bezier曲線_貝塞爾曲線
  1. 示範給出點的全部變化(7階,12階用這個畫的)
from matplotlib import pyplot as plt
from bezier import illustrate

fig = plt.figure()

points = [[0, 0], [3, 3], [6, 0]]
b = illustrate(fig, points, interval=50, n=100, depth=3)
plt.xlim(-1, 7)
plt.ylim(-1, 5)

plt.show()
           

2. 僅僅示範曲線運動

from matplotlib import pyplot as plt
from bezier import sketch

fig = plt.figure()
plt.xlim(-1, 11)
plt.ylim(-2, 8)
b = sketch(fig, [[0, 0], [5, 5], [10, 0]], color='b')
plt.show()
           

3. 單點單線運動

from matplotlib import pyplot as plt
from bezier import Bezier
import numpy as np

fig = plt.figure()
plt.xlim(0, 10)
plt.ylim(0, 10)
left_x = np.linspace(2, 8, 100)
left_y = [8 for x in range(100)]
right_x = np.linspace(2, 8, 100)
right_y = [2 for x in range(100)]
b = Bezier(fig)
a1 = b.vector_animate(left_x, left_y, right_x, right_y, color='k', no_line=True)
a2 = b.line_animate(left_x, left_y, right_x, right_y, color='b')
plt.show()