3.1.問題描述
在數學世界中有一些美麗的曲線圖形,有螺旋線、擺線、雙紐線、蔓葉線且、心臟線、漸開線、玫瑰曲線、蝴蝶曲線…… 這些形狀各異、簡有繁別的數學曲線圖形爲看似枯燥的數學公式披上精彩紛呈的美麗衣裳。
在數學曲線的百花園中,玫瑰曲線算得上箇中翹楚,它的數學方程簡單,曲線變化衆多,根據參數的變化能展現出姿態萬千的優美形狀。玫瑰曲線可用極座標方程表示爲
圖一、三葉玫瑰曲線
3.2.問題描述
在數學世界中,像玫瑰曲線這樣美麗的曲線圖形實際上是由簡單的函數關係生成的。通過利用曲線函數的參數方程,可以在平面直角座標系中方便地繪製出它們的圖形。
假如要利用玫瑰曲線的參數方程繪製三葉玫瑰曲線,則參數n的值可以設定爲3,參數a的值可以設定葉子的長度(如 100)。因爲參數 n=3 是奇數,所以三葉玫瑰曲線的閉合週期爲π。 只要將參數 θ從0變化到 π,就能利用玫瑰曲線的參數方程求出平面內的一系列連續的點的座標(x,y),由此可構成三葉玫瑰曲線的圖形。
繪製玫瑰曲線的編程思路: 在一個循環結構中讓參數 θ從 0 變化到π,再利用玫瑰曲線的參數方程求出點座標x和y的值,並通過海龜繪圖庫繪製一系列連續的點,最終繪製出一個完整的玫瑰曲線圖。
3.3.編程解題
根據上述算法分析中給出的編程思路,編程繪製玫瑰曲線的圖形。這個案例需要用到海龜繪圖的知識.,請回顧上一節介紹的海龜繪圖方法。
首先我們來看Python的代碼:
1 ''' 2 程序:繪製玫瑰曲線 3 作者:蘇秦@小海豚科學館公衆號 4 來源:圖書《Python趣味編程:從入門到人工智能》 5 ''' 6 from turtle import * 7 from math import * 8 9 def draw(a, n, end): 10 '''繪製玫瑰曲線''' 11 t = 0 12 while t <= end: 13 x = a * sin(n * t) * cos(t) 14 y = a * sin(n * t) * sin(t) 15 goto(x, y) 16 t = t + 0.01 17 18 if __name__ == '__main__': 19 '''三葉玫瑰''' 20 draw(100, 3, 3.14) 21 '''六葉玫瑰''' 22 #draw(100, 1.5, 12.56)
在上面的代碼中可以看出,Python除了要導入海龜繪圖庫外,還要導入數學庫,因爲玫瑰曲線函數中涉及三角函數,需要用到 Python 內置的數學庫。
用於繪製玫瑰曲線的 draw()函數有3個參數,其中參數變量 a 表示葉子的長度,參數變量 n 表示葉子的數量,參數變量 end 表示曲線閉合週期。
在函數體中,通過 while 循環結構畫出一系列連續的點,循環變量爲t,循環控制條件爲 t <= end,即在從 0 到 end 的範圍內繪製一個閉合的玫瑰曲線。
在循環體中,使用玫瑰曲線的參數方程求出點座標 x 和 y 的值,再利用海龜繪圖庫提供的 goto(x,y)函數定位畫筆就能繪製出相應的圖形。 爲了繪製出平滑的曲線,循環變量t每次以0.01 的幅度增加。
上面代碼中的main函數中“三頁玫瑰”的代碼調用 draw()繪製出一個葉子長度爲 100 的三葉玫瑰曲線。由於葉子數3是奇數,所以閉合週期爲π ,這裏選取 3.14 即可。它繪出的圖形如下:
然而“六葉玫瑰”的參數n=1.5,end=12.56,這又是怎麼得來的呢?下面我們來討論玫瑰線參數的特性。
當在整數範圍內討論參數n時,玫瑰曲線的參數特性:若n爲奇數,則玫瑰曲線n個葉子數,閉合週期爲π,即θ取值爲0~ π;若n爲偶數,玫瑰曲線2n個葉子數,閉合週期爲2π ,即θ取值爲 0~2π。
當在有理數範圍內討論參數n時,可利用公式 確定玫瑰曲線的葉子數和閉合週期。n爲非整數的有理數,L/W爲簡約分數,參數L控制葉子數,參數W控制閉合週期。玫瑰曲線的參數特性:當參數L和W僅有一個是偶數時,則閉合週期爲2Wπ,葉子數爲2L;當參數L和W都是奇數時,則閉合週期爲Wπ ,葉子數爲L。
在下圖中展示的是玫瑰曲線 7 代圖譜,位於頂端的數字表示參數 L 的值,位於左端的數字表示參數W 的值,通過選擇 L 和W 的值,就能確定玫瑰曲線的圖形。
所以,當 L=3、W=2 時,則n=1.5,閉合週期爲 2Wπ =12.56。 根據這兩個參數就可以繪製出六葉玫瑰曲線圖形。如下圖:
好了,我們已經知道了繪製玫瑰曲線的原理,轉換爲Julia語言來實現相比也不困難。
當然還是要請出Julia的海龜繪圖庫Luxor,在上一節中已有介紹。不過,筆者在Luxor中沒有找到類似Python海龜繪圖庫turtle中的goto()函數,所以只能自主實現了自定義函數Goto()。
完整代碼如下:
1 """ 2 程序:Julia繪製玫瑰曲線 3 Python原作者:蘇秦@小海豚科學館公衆號 4 來源:圖書《Python趣味編程:從入門到人工智能》 5 """ 6 7 using Luxor 8 9 #實現海龜畫線,從原座標點到目標座標點 10 function Goto(t::Turtle,p::Point) 11 oldx, oldy = t.xpos, t.ypos 12 t.xpos=p.x 13 t.ypos=p.y 14 if t.pendown 15 gsave() 16 sethue(t.pencolor...) 17 line(Point(oldx, oldy), Point(t.xpos, t.ypos), :stroke) 18 grestore() 19 end 20 end 21 22 #繪製玫瑰曲線''' 23 function draw(t::Turtle,a, n, stop) 24 s = 0 25 while s <= stop 26 x = a * sin(n * s) * cos(s) 27 y = a * sin(n * s) * sin(s) 28 Goto(t,Point(x,y)) 29 s = s + 0.01 30 end 31 end 32 function main() 33 Drawing(300, 300, "mgqx.svg") 34 origin() 35 turtle=Turtle() 36 #三葉玫瑰曲線 37 draw(turtle,100, 3, 3.14) 38 finish() 39 end 40 main()
繪製的三葉玫瑰圖如下:
可以發現,上圖與Python繪製的三葉玫瑰曲線上下顛倒了,當然這關係不大,只能說明Luxor的海龜與Python的turtle移動方向是相反的。
- 擴展閱讀
在用海龜繪圖庫實現繪製玫瑰曲線之後,我們並不打算就此停步。因爲原書作者是用參數方方程作爲編程的數學模型:
而我們打算迴歸玫瑰曲線的極座標方程:
ρ=a∗sinθ
而且,無論是Python還是Julia都有豐富的科學計算和數據可視化繪圖庫,相比於海龜繪圖庫更加高效。因此我們用極座標方程作爲數學模型,並採用其它可視化庫來看看如何繪製玫瑰曲線。
經過這麼些年的發展,Julia的繪圖庫也日漸豐富,比較常用的有Gadfly, Plots, PyPlot庫等,大家可以在下面的網址查看這些庫的說明:https://juliapackages.com/c/graphics。
本文選用PyPlot.jl庫來實現繪製玫瑰曲線。PyPlot庫實際上是一個經典的Python繪圖庫Matplotlib的一個模塊,PyPlot.jl提供了一個接口用於調用Matplotlib.PyPlot模塊,所以在使用它之前需要先安裝matplotlib:
方法一,使用pip安裝matplotlib
pip install matplotlib
方法二,使用pip安裝光速安裝matplotlib如果安裝太慢,可替換國內的下載源
pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple
然後我們用之前介紹的Julia的庫安裝方法來安裝PyPlot.jl庫,或者直接在Julia終端環境輸入using PyPlot,然後根據提示操作即可。
所謂玫瑰曲線就是在平面內,圍繞某一中心點平均分佈整數個正弦花瓣的曲線,在極座標下可表示爲ρ=a*sin(nθ),a爲定長,n爲整數,來看完整代碼:
1 using PyPlot 2 function draw() 3 theta=0:0.01:2*pi 4 #上面返回一個array對象,其元素從0-2*pi,步長0.01 5 subplot(111,polar=true) #設置爲極座標模式 6 #6瓣花瓣 7 plot(theta,sin.(6*theta),linewidth=2.0, linestyle="-") 8 #5瓣花瓣 9 plot(theta,sin.(5*theta),linewidth=2.0, linestyle="--") 10 #4瓣花瓣 11 plot(theta,2*sin.(4*theta),linewidth=2) 12 rgrids((0.5:0.5:2),angle=45) #網格線 13 thetagrids([0,45,90])#角度值 14 show() 15 end 16 draw()
運行後,會打開一個圖形窗口,顯示所畫的圖形:
怎麼樣,是不是很漂亮!