python與分形0015 - 【教程】五星紅旗

不知不覺,今天又周五,513330都快破6了,倒金字塔加倉都加到地下室了,真是服氣了。

在前幾節(jié)的教程中,我們玩了一些奇怪的事情,今天我們來玩?zhèn)€正經的事情,畫一面五星紅旗,也就是我們的國旗。

閑話不說,先上成品圖。

繪制視頻如下:

余額不足的程序員 ,
五星紅旗 #分形 #python
視頻號

話不多說,還是上教程。

國旗和數學

在畫國旗之前,我們需要弄清楚國旗的圖形結構。

根據1949年9月28日中國人民政治協(xié)商會議第一屆全體會議主席團公布的《國旗制法說明》,中華人民共和國國旗旗面為紅色,長方形,其長與高為三與二之比,旗面左上方綴黃色五角星五顆。一星較大,其外接圓直徑為旗高十分之三,居左;四星較小,其外接圓直徑為旗高十分之一,環(huán)拱于大星之右。旗桿套為白色。

中華人民共和國國旗的紅色象征革命。旗上的五顆五角星及其相互關系象征共產黨領導下的革命人民大團結。五角星用黃色是為了在紅地上顯出光明,黃色較白色明亮美麗,四顆小五角星各有一尖正對著大星的中心點,這是表示圍繞著一個中心而團結,在形式上也顯得緊湊美觀。

如下圖所示:

我們把它轉化為數學關系(假設國旗中心點為坐標系原點(0,0),每個格子長寬為L):

  1. 國旗的四個頂點為(-15L,10L),(15L,10L),(15L,-10L),(-15L,-10L)
  2. 大五角星中心點為(-10L,5L),半徑為3L,水平放置
  3. 小五角星A中心點為(-5L,8L),半徑為L,tan(A)=3/5
  4. 小五角星B中心點為(-3L,6L),半徑為L,tan(B)=1/7
  5. 小五角星C中心點為(-3L,3L),半徑為L,tan(C)=2/7
  6. 小五角星D中心點為(-5L,1L),半徑為L,tan(A)=4/5

這個是我們后面繪圖的基礎,先放這里了。

開始畫圖

先來畫旗面,是一個簡單的矩形,其思路很簡單:

  1. 從左上頂點開始,往東,seth(0),走30L的長度。
  2. 再往南,seth(-90),走20L的長度。
  3. 再往西,seth(180),走30L的長度。
  4. 最后往北,seth(90),走20L的長度。
  5. fill為紅色。

代碼如下:

def?rectangle(center,?length_x,?length_y,?penc,?fillc):
????turtle.pensize(1)
????turtle.fillcolor(fillc)
????turtle.pencolor(penc)
????turtle.up()
????pos=(center[0]-length_x/2,?center[1]+length_y/2)
????turtle.goto(pos)
????turtle.begin_fill()
????turtle.down()
????turtle.seth(0)
????turtle.fd(length_x)
????turtle.seth(-90)
????turtle.fd(length_y)
????turtle.seth(180)
????turtle.fd(length_x)
????turtle.seth(90)
????turtle.fd(length_y)
????turtle.end_fill()

再來畫五角星,我們先來分解,畫一個正五角星。

同樣的,我們先把數學關系弄出來,見下圖:

假設圓的半徑為L。

我們先來找到邊長關系,因為:sin(54) = T / L0 且 sin(36) = T / L,得到:L0 = L * sin(36) / sin(54),即五角星的邊長。

我們觀察到五角星的邊具有可復制性,A-C1-B重復畫5次即可,那么我們先把A-C1-B畫出來。

  1. 先不要下筆,從O出發(fā),向北,seth(90),走L的長度,現在在A點。
  2. 向西南方向,seth(180+72),做準備。
  3. 落筆,走L0的長度,到C1點。
  4. 右轉72度,right(72),走L0的長度,到B點。
  5. 至此,A-C1-B就畫好了。
  6. 然后我們把方向轉到下一次畫圖的方向,左轉144度,left(144)。
  7. 重復3-6的動作4次,即可完成整個圖形。
  8. 最后fill為黃色。

代碼如下:

def?star(pos,?length,?penc,?fillc):
????turtle.pensize(1)
????turtle.fillcolor(fillc)
????turtle.pencolor(penc)
????L?=?length*math.sin(36*math.pi/180)/math.sin(54*math.pi/180)
????turtle.up()
????turtle.goto(pos)
????turtle.seth(90)
????turtle.fd(length)
????turtle.seth(180+72)
????turtle.down()
????turtle.begin_fill()
????for?_?in?range(5):
????????turtle.fd(L)
????????turtle.right(72)
????????turtle.fd(L)
????????turtle.left(144)
????turtle.end_fill()

五角星我們已經畫出來了,現在我們需要給它旋轉一個角度。

這時,我們發(fā)現,繪圖的過程中,五角星的角度在down之前就已經調整好了,后面畫5條折線的時候都是相對位置。

OK,我們把函數改吧改吧就可以了:

def?star(pos,?angle,?length,?penc,?fillc):
????turtle.pensize(1)
????turtle.fillcolor(fillc)
????turtle.pencolor(penc)
????L?=?length*math.sin(36*math.pi/180)/math.sin(54*math.pi/180)
????turtle.up()
????turtle.goto(pos)
????turtle.seth(90+angle)
????turtle.fd(length)
????turtle.seth(180+72+angle)
????turtle.down()
????turtle.begin_fill()
????for?_?in?range(5):
????????turtle.fd(L)
????????turtle.right(72)
????????turtle.fd(L)
????????turtle.left(144)
????turtle.end_fill()

再來看,旋轉20°:

star((0,?0),?0,?90,?'yellow',?'yellow')
star((150,?0),?20,?90,?'red',?'red')

OK,到此,萬事俱備,只欠代碼。

畫國旗

所有的細節(jié)都說清楚了,直接上代碼吧!??!

#coding:?utf-8

import?turtle
import?time
import?math

turtle.setup(width=1.0,?height=1.0,?startx=None,?starty=None)
turtle.ht()
turtle.tracer(0,?0)
turtle.bgcolor("black")

turtle.pensize(1)

def?star(center,?angle,?length,?penc,?fillc):
????turtle.pensize(1)
????turtle.fillcolor(fillc)
????turtle.pencolor(penc)
????L?=?length*math.sin(36*math.pi/180)/math.sin(54*math.pi/180)????
????turtle.up()
????turtle.goto(center)
????turtle.seth(90+angle)
????turtle.fd(length)
????turtle.seth(180+72+angle)
????turtle.down()
????turtle.begin_fill()
????for?_?in?range(5):
????????turtle.fd(L)
????????turtle.right(72)
????????turtle.fd(L)
????????turtle.left(144)
????turtle.end_fill()

def?rectangle(center,?length_x,?length_y,?penc,?fillc):
????turtle.pensize(1)
????turtle.fillcolor(fillc)
????turtle.pencolor(penc)
????turtle.up()
????pos=(center[0]-length_x/2,?center[1]+length_y/2)
????turtle.goto(pos)
????turtle.begin_fill()
????turtle.down()
????turtle.seth(0)
????turtle.fd(length_x)
????turtle.seth(-90)
????turtle.fd(length_y)
????turtle.seth(180)
????turtle.fd(length_x)
????turtle.seth(90)
????turtle.fd(length_y)
????turtle.end_fill()

W?=?1200
H?=?800
dW?=?W/30
dH?=?H/20

#time.sleep(6)

rectangle((0,0),?W,?H,?'red',?'red')
C0?=?(-dW*10,?dH*5)
A0?=?0
L0?=?dW*3
star(C0,?A0,?L0,?'yellow',?'yellow')
C1?=?(-dW*5,?dH*8)
A1?=?90+math.atan(3/5)*180/math.pi
L1?=?dW
star(C1,?A1,?L1,?'yellow',?'yellow')
C2?=?(-dW*3,?dH*6)
A2?=?90+math.atan(1/7)*180/math.pi
L2?=?dW
star(C2,?A2,?L2,?'yellow',?'yellow')
C3?=?(-dW*3,?dH*3)
A3?=?90-math.atan(2/7)*180/math.pi
L3?=?dW
star(C3,?A3,?L3,?'yellow',?'yellow')
C4?=?(-dW*5,?dH)
A4?=?90-math.atan(4/5)*180/math.pi
L4?=?dW
star(C4,?A4,?L4,?'yellow',?'yellow')
余額不足的程序員 ,
五星紅旗 #分形 #python
視頻號

本文使用 文章同步助手 同步

?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容