用 Python 繪制一個 Facebook 元宇宙新 Logo
Facebook 為了投身元宇宙,連名字都改了 Meta,也更換了 LOGO。

但這個 LOGO 似乎不是藝術(shù)家憑感覺設(shè)計的,而是有來頭的,在數(shù)學(xué)上稱為 Lissajous 曲線。
平面上的 Lissajous 曲線可以看成是沿著相互垂直方向的兩個正弦振動的合成,具體是由以下參數(shù)方程描述的一系列曲線:
Lissajous 曲線在物理學(xué)、天文學(xué)和其他科學(xué)中都有應(yīng)用。下面是一些 Lissajous 曲線示例,你可以通過更改 Python 代碼中常量 A 和 B 的值,塑造出更多的具體曲線。

下面就讓我們用 Python 來試著繪制一下這個 LOGO。
import?numpy?as?np
import?matplotlib?as?mpl
import?matplotlib.pyplot?as?plt
plt.style.use('Solarize_Light2')
import?seaborn?as?sns
sns.set_style("white")
所謂參數(shù)曲線,就是要根據(jù)參數(shù)來確定曲線上的每一個點(diǎn)。也就是說在繪制時,我們需要根據(jù)參數(shù)來取不同點(diǎn)的
設(shè)置常量參數(shù) 、 、 、 以及 ,控制曲線整體的形狀。
A,?B?=?1,?1
delta?=?3.14159/2
設(shè)置曲線上采樣點(diǎn)的參數(shù)向量 。我們先取 50 個點(diǎn),便于觀察點(diǎn)在曲線上的分布。
t?=?np.linspace(0,?2*np.pi,?50)
fig?=?plt.figure(figsize=(8,4.5))
a?=?1?
b?=?2
x?=?A?*?np.sin(a*t?+?delta)?
y?=?B?*?np.sin(b*t)?
plt.plot(x,?y,?'-o');

這畫出來了一個無窮大
我們不妨將上述內(nèi)容寫在一起,定義一個簡單的函數(shù),方便后面調(diào)用。
def?drawLissajous2D(r=10,n=500,A=1,B=1,a=1,b=1,delta=1.75,lw=2):
????
????t?=?np.linspace(0,?r,?n)
????
????fig?=?plt.figure(figsize=(8,4.5))
????x?=?A?*?np.sin(a*t?+?delta)?
????y?=?B?*?np.sin(b*t)?
????plt.plot(x,?y,?'-',linewidth=lw)
為了更方便觀察曲線上繪制的點(diǎn)列,我們將參數(shù)
t?=?np.linspace(0,?np.pi,?50)
fig?=?plt.figure(figsize=(8,4.5))
a?=?1?
b?=?2
x?=?A?*?np.sin(a*t?+?delta)?
y?=?B?*?np.sin(b*t)?
plt.plot(x,?y,?'-o');

上面只看到了無窮大的一半,因為只畫了半個周期。把這些點(diǎn)想象成動點(diǎn),將其兩個坐標(biāo)分開考慮,
取 500 個點(diǎn),調(diào)整下 和 的值,再次繪制曲線。曲線的樣子是不是改變了,上下并不對稱了。
drawLissajous2D(n=500,a=1,b=2)

調(diào)整常量參數(shù)以及線條的寬度
drawLissajous2D(n=500,a=1,b=2,lw=12)

看看其他參數(shù)畫出來的是個啥?
drawLissajous2D(n=300,a=1,b=1,delta=3.14159/2,lw=6)

drawLissajous2D(n=300,a=3,b=9,lw=6)

13D 版本
還可以二維版本的 Lissajous 曲線擴(kuò)展到三維空間中,得到三維版本的空間 Lissajous 曲線。只要增加一個
from?mpl_toolkits?import?mplot3d
%matplotlib?notebook
import?numpy?as?np
import?matplotlib.pyplot?as?plt
import?matplotlib
matplotlib.rc('xtick',?labelsize=8)
matplotlib.rc('ytick',?labelsize=8)
def?drawLissajous3D(r=2*np.pi,n=500,A=1,B=1,C=1,a=1,b=1,c=2,delta=1.75,epsilon=1.75):
????#?設(shè)置 Lissajous 參數(shù)。
????t?=?np.linspace(0,?r,?n)
????x?=?A?*?np.sin(a*t)?
????y?=?B?*?np.sin(b*t?+?delta)?
????z?=?C?*?np.sin(c*t?+?epsilon)?
????plt.figure(figsize=(8,6))
????ax?=?plt.axes(projection='3d')
????ax.plot3D(x,?y,?z,?'-',?linewidth=6)
????ax.set_xlabel('$x?=?A?sin(at)$',?fontsize=12)
????ax.set_ylabel('$y?=?B?sin(bt?+?\delta)$',?fontsize=12)
????ax.set_zlabel('$z?=?C?sin(ct?+?\epsilon)$',?fontsize=12)
????plt.title("Lissajous?3D?Curve",?fontsize=12)
????ax.view_init(2,?60)
drawLissajous3D()

可以在窗口中用鼠標(biāo)交互,比如轉(zhuǎn)動看看,

如果有興趣,可以將上述繪制改成旋轉(zhuǎn)動畫,讓這個 LOGO 在三維空間中動起來哦。
