從turtle海龜動畫 學習 Python - 高中彈性課程系列 6.1 內嵌正多邊形 類似禪繞圖

47 篇文章 1 订阅
33 篇文章 1 订阅
这篇博客介绍了使用Python的turtle模块进行基础和进阶的图形绘制,包括内嵌正多边形、禅绕图等。通过一系列教程,读者将学习如何利用余弦定律和正弦定律计算转角和步长,实现复杂的图案创作。内容涵盖递归、分形和对象导向编程,适合高中阶段学习Python编程的学生。
摘要由CSDN通过智能技术生成

Goal: 藉由有趣的「海龜動畫繪圖」學會基礎的 Python 程式設計
本篇介紹基礎的 Python 海龜動畫繪圖, 確實可以只以簡單的指令畫出極為複雜有趣或美麗的圖案: 內嵌正多邊形之圖案, 禪繞圖等

“Talk is cheap. Show me the code.”
― Linus Torvalds

老子第41章
上德若谷
大白若辱
大方無隅
大器晚成
大音希聲
大象無形
道隱無名

拳打千遍, 身法自然

“There’s no shortage of remarkable ideas, what’s missing is the will to execute them.” – Seth Godin
「很棒的點子永遠不會匱乏,然而缺少的是執行點子的意志力。」—賽斯.高汀

本系列文章之連結

  • 從turtle海龜動畫學習Python-高中彈性課程1 link
  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 2 安裝 Python, 線上執行 Python link
  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 3 烏龜繪圖 所需之Python基礎 link
  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 4 烏龜開始畫圖 link
  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 5 用函數封裝重複性指令-呼叫函數令烏龜畫正 n 邊形 link
  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 6 畫多重旋轉圓,螺旋正方形 link
  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 6.1 內嵌正多邊形 類似禪繞圖 link
  • 從turtle海龜動畫 學習 Python - 7 遞歸 recursive - 高中彈性課程系列 link
  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 8 碎形 (分形 fractal) link
  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 8.1 碎形 L-system link
  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 9 Python 物件導向介紹 link
  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 9.1 Python 物件導向的練習 link
  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 10 藝術畫 link
  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 11.1 氣泡排序 - 用 turtle 呈現演算法之執行動作 link
  • 從turtle海龜動畫 學習 Python - 高中彈性課程系列 11.2 maze 迷宮 - 用 turtle 呈現演算法之執行動作 link

Python 畫內嵌正方形 用到商高定理

以下我們先在黑板計算正四邊形內嵌圖, 所需的參數資料, 用到商高定理與反正切的定義即可, 也就是給定邊長 A B AB AB 與步進比例 α \alpha α, 正n邊形之邊數 n n n, 以此表達 θ \theta θ(海龜之轉角) 與 H I HI HI(海龜前進之步長):
20221109_第10週_Python_內嵌正多邊形_正四邊形用反正切_黑板計算

Python 畫內嵌正方形形_20221109

# Python 畫內嵌正方形
# 20221109 By Peng-Jen Lai MATH NKNU
# 內嵌正方形只需用畢氏定理與與反正切計算出
# Python 畫內嵌正方形_簡化_20221109.py

import math  
import turtle 
T=turtle.Turtle()
T.shape("turtle")
T.color("green")
T.pencolor("yellow")
T.turtlesize(1)
turtle.bgcolor("black") 
T.pensize(1)
def polygon(n, sideLength):
    for i in range(n):
        T.fd(sideLength)
        T.lt(360.0/n)

sideLength=300
turnNumber=3
#newSideLength=sideLength
turnAngle=0
sideNumber=4

shrinkingFactor=0.4
#stepLength=newSideLength*shrinkingFactor
for i in range(turnNumber):
     polygon(sideNumber,sideLength)
     stepLength=sideLength*shrinkingFactor
     T.fd(stepLength)
     turnAngle=math.atan(shrinkingFactor/(1-shrinkingFactor))*180/math.pi
     # *180/pi 是因為要由radians弧度改成degree角度
     T.lt(turnAngle)
     # 以下是更新下一輪正方形之邊長的動作
     sideLength=math.sqrt( shrinkingFactor**2+(1-shrinkingFactor)**2 )*sideLength

Ex: 將以上之程式碼, 改成封裝在一個函數中, 例如
f( length=300, alpha=0.4, turnNumber=3 ).
其中:
length=300 表示指定之邊長,
alpha=0.4 表示指定之步進收縮比例
turnNumber=3 表示所有內嵌之正n邊形, 並包括最外層正n邊形, 之總個數, 為 3 個.
Answer:

Python 畫內嵌正多邊形_fun_20221123

Python 畫內嵌正多邊形 用到餘弦定律與正弦定律

內嵌正多邊形_在黑板畫正五邊形的相關長度的計算_補上正弦定律的應用
對於正 n 邊形, 上一節對內嵌正四邊形的計算就需要修正推廣,
根據上面圖片黑板上的計算, 給定邊長 A B AB AB 與步進比例 α \alpha α, 正n邊形之邊數 n n n, 以此表達 θ \theta θ(海龜之轉角) 與 H I HI HI(海龜前進之步長):與內嵌正四邊形之計算不同, 內嵌正 n 邊形時, 海龜前進之步長與海龜之轉角重新用餘弦定律與正弦定律計算出, 據此新獲得的參數, 用來修改上面內嵌正四邊形的codes,
得到以下的海龜畫內嵌正 n 邊形的 codes,

Python 畫內嵌正多邊形_20221116

# Python 畫內嵌正多邊形
# 20221116 By Peng-Jen Lai MATH NKNU
# 內嵌正多邊形, 重新用餘弦定律與正弦定律計算出
# Python 畫內嵌正多邊形_20221116.py
##註: 先用分解動作試跑, 再寫成迴圈, 較不會出現更新順序之錯誤!

import math  
import turtle 
T=turtle.Turtle()
T.shape("turtle")
T.color("green")
T.pencolor("yellow")
T.turtlesize(1)
turtle.bgcolor("black") 
T.pensize(1)
def polygon(n, sideLength):
    for i in range(n):
        T.fd(sideLength)
        T.lt(360.0/n)

AB=300
turnNumber=5
n=5
alpha=0.4
beta=(n-2)/n*math.pi
c=AB

for i in range(turnNumber):
    polygon(n,c)

    a=c*alpha
    b=c*(1-alpha)
    beta=(n-2)/n*math.pi
    c=c*math.sqrt(alpha**2+(1-alpha)**2-2*alpha*(1-alpha)*math.cos(beta) )
    theta=math.asin(a/c*math.sin(beta))
    T.fd(a)
    T.lt(theta*180/math.pi)


#################################################
##註:
##先用分解動作試跑, 再寫成迴圈, 較不會出現更新順序之錯誤!
##
##AB=300
##turnNumber=3
##
##n=5
##
##alpha=0.4
##beta=(n-2)/n*math.pi
##c=AB
##polygon(n,c)
##
##a=AB*alpha
##b=AB*(1-alpha)
##beta=(n-2)/n*math.pi
##c=c*math.sqrt(alpha**2+(1-alpha)**2-2*alpha*(1-alpha)*math.cos(beta) )
##
##theta=math.asin(a/c*math.sin(beta))
##T.fd(a)
##T.lt(theta*180/math.pi)
##polygon(n,c)
##
##
##a=c*alpha
##b=c*(1-alpha)
##beta=(n-2)/n*math.pi
##c=c*math.sqrt(alpha**2+(1-alpha)**2-2*alpha*(1-alpha)*math.cos(beta) )
##theta=math.asin(a/c*math.sin(beta))
##T.fd(a)
##T.lt(theta*180/math.pi)
##polygon(n,c)
##
##
##a=c*alpha
##b=c*(1-alpha)
##beta=(n-2)/n*math.pi
##c=c*math.sqrt(alpha**2+(1-alpha)**2-2*alpha*(1-alpha)*math.cos(beta) )
##theta=math.asin(a/c*math.sin(beta))
##T.fd(a)
##T.lt(theta*180/math.pi)
##polygon(n,c) 

Ex: 將以上之程式碼, 改成封裝在一個函數中, 例如f(sideNumber=5, length=300, alpha=0.4, turnNumber=3 ).
其中:
sideNumber=5 表示指定正5邊形
length=300 表示指定之邊長,
alpha=0.4 表示指定之步進收縮比例
turnNumber=3 表示所有內嵌之正n邊形, 並包括最外層正n邊形, 之總個數, 為 3 個.

# Python 畫內嵌正多邊形, 封裝成函數
# 20221116 By Peng-Jen Lai MATH NKNU
# 內嵌正多邊形, 重新用餘弦定律與正弦定律計算出
# Python 畫內嵌正多邊形_fun_20221123.py
##註: 先用分解動作試跑, 再寫成迴圈, 較不會出現更新順序之錯誤!

import math  
import turtle 
T=turtle.Turtle()
T.penup()
T.goto(-200,-200)
T.pendown()
T.shape("turtle")
T.color("green")
T.pencolor("yellow")
T.turtlesize(1)
turtle.bgcolor("black") 
T.pensize(1)
def polygon(n, sideLength):
    for i in range(n):
        T.fd(sideLength)
        T.lt(360.0/n)

def imbededRegPoly(n=3, length=300, imbededNumber=8, alpha=0.2):
    beta=(n-2)/n*math.pi
    c=length

    for i in range(imbededNumber):
        polygon(n,c)

        a=c*alpha
        b=c*(1-alpha)
        beta=(n-2)/n*math.pi
        c=c*math.sqrt(alpha**2+(1-alpha)**2-2*alpha*(1-alpha)*math.cos(beta) )
        theta=math.asin(a/c*math.sin(beta))
        T.fd(a)
        T.lt(theta*180/math.pi)

imbededRegPoly()
#################################################
##註:
##先用分解動作試跑, 再寫成迴圈, 較不會出現更新順序之錯誤!
##
##AB=300
##turnNumber=3
##
##n=5
##
##alpha=0.4
##beta=(n-2)/n*math.pi
##c=AB
##polygon(n,c)
##
##a=AB*alpha
##b=AB*(1-alpha)
##beta=(n-2)/n*math.pi
##c=c*math.sqrt(alpha**2+(1-alpha)**2-2*alpha*(1-alpha)*math.cos(beta) )
##
##theta=math.asin(a/c*math.sin(beta))
##T.fd(a)
##T.lt(theta*180/math.pi)
##polygon(n,c)
##
##
##a=c*alpha
##b=c*(1-alpha)
##beta=(n-2)/n*math.pi
##c=c*math.sqrt(alpha**2+(1-alpha)**2-2*alpha*(1-alpha)*math.cos(beta) )
##theta=math.asin(a/c*math.sin(beta))
##T.fd(a)
##T.lt(theta*180/math.pi)
##polygon(n,c)
##
##
##a=c*alpha
##b=c*(1-alpha)
##beta=(n-2)/n*math.pi
##c=c*math.sqrt(alpha**2+(1-alpha)**2-2*alpha*(1-alpha)*math.cos(beta) )
##theta=math.asin(a/c*math.sin(beta))
##T.fd(a)
##T.lt(theta*180/math.pi)
##polygon(n,c)

######################################
# 以下是更新順序錯誤之紀錄:

畫內嵌正多邊形禪繞圖

我們參考許正輝老師用Geogebra畫的 多邊形纏繞畫作
許正輝老師用Geogebra畫的 多邊形纏繞畫作

重複4個內嵌三角形組成初步之纏繞圖

改用 Python 畫.
Python 畫內嵌正多邊形_fun_禪繞_20221123.py
Python 畫內嵌正多邊形_fun_禪繞2_20221123.py

程式碼如下:


```python
# Python 畫內嵌正多邊形, 封裝成函數, 畫禪繞圖
# 20221123 By Peng-Jen Lai MATH NKNU
# 重複4個內嵌三角形組成初步之纏繞圖
# Python 畫內嵌正多邊形_fun_禪繞_20221123.py


import math  
import turtle 
T=turtle.Turtle()
T.penup()
startPoint=(-200,-200)
#T.goto(-200,-200)
T.goto(startPoint)
T.pendown()
T.shape("turtle")
T.color("green")
T.pencolor("yellow")
T.turtlesize(1)
turtle.bgcolor("black") 
T.pensize(1)
def polygon(n, sideLength):
    for i in range(n):
        T.fd(sideLength)
        T.lt(360.0/n)

def imbededRegPoly(n=3, length=300, imbededNumber=5, alpha=0.2):
    beta=(n-2)/n*math.pi
    c=length

    for i in range(imbededNumber):
        polygon(n,c)

        a=c*alpha
        b=c*(1-alpha)
        beta=(n-2)/n*math.pi
        c=c*math.sqrt(alpha**2+(1-alpha)**2-2*alpha*(1-alpha)*math.cos(beta) )
        theta=math.asin(a/c*math.sin(beta))
        T.fd(a)
        T.lt(theta*180/math.pi)


length=300
halfLength = length/2

altitude = halfLength* math.sqrt(3)/2
x, y= -200, -200
T.penup()
#startPoint=(x+length/4,y+length/2)
startPoint=(x+length/4,y+altitude)
T.goto(startPoint)
T.pendown()
T.setheading(0)
imbededRegPoly(length=150)

T.penup()
startPoint=(x,y)
T.goto(startPoint)
T.pendown()
T.setheading(0)
imbededRegPoly(length=150)


T.penup()
startPoint=(x,y)
T.goto(x+length/2,y)
T.pendown()
T.setheading(0)
imbededRegPoly(length=150)


T.penup()
startPoint=(x,y)
T.goto(x+length/2,y)

T.pendown()
T.setheading(0)
T.lt(60)
imbededRegPoly(length=150)

Ex: 將以上之程式碼, 改成封裝在一個函數中
Ans:

# Python 畫內嵌正多邊形, 封裝成函數, 畫禪繞圖
# 20221130 By Peng-Jen Lai MATH NKNU
# 重複4個內嵌三角形組成初步之纏繞圖
# 以下是畫4個內嵌三角形, 封裝成函數
# Python 畫內嵌正多邊形_fun_禪繞_20221130.py

import math  
import turtle 
T=turtle.Turtle()
T.penup()
startPoint=(-200,-200)
#T.goto(-200,-200)
T.goto(startPoint)
T.pendown()
T.shape("turtle")
T.color("green")
T.pencolor("yellow")
T.turtlesize(1)
turtle.bgcolor("black") 
T.pensize(1)
def polygon(n, sideLength):
    for i in range(n):
        T.fd(sideLength)
        T.lt(360.0/n)

def imbededRegPoly(n=3, length=500, imbededNumber=10, alpha=0.1):
    beta=(n-2)/n*math.pi
    c=length

    for i in range(imbededNumber):
        polygon(n,c)

        a=c*alpha
        b=c*(1-alpha)
        beta=(n-2)/n*math.pi
        c=c*math.sqrt(alpha**2+(1-alpha)**2-2*alpha*(1-alpha)*math.cos(beta) )
        theta=math.asin(a/c*math.sin(beta))
        T.fd(a)
        T.lt(theta*180/math.pi)


#length=500


def tripleImbededRegPoly(n=3, length=500, imbededNumber=10, alpha=0.1):
    halfLength = length/2
    altitude = halfLength* math.sqrt(3)/2
    x, y= -200, -200

    # 畫上方三角形
    T.penup()
    #startPoint=(x+length/4,y+length/2)
    startPoint=(x+length/4,y+altitude)
    T.goto(startPoint)
    T.pendown()
    T.setheading(0)
    imbededRegPoly(length=halfLength)

    # 畫左下方三角形
    T.penup()
    startPoint=(x,y)
    T.goto(startPoint)
    T.pendown()
    T.setheading(0)
    imbededRegPoly(length=halfLength)

    # 畫右下方三角形
    T.penup()
    startPoint=(x,y)
    T.goto(x+length/2,y)
    T.pendown()
    T.setheading(0)
    imbededRegPoly(length=halfLength)

    # 畫中間三角形
    T.penup()
    startPoint=(x,y)
    T.goto(x+length/2,y)
    T.pendown()
    T.setheading(0)
    T.lt(60)
    imbededRegPoly(length=halfLength)

重複9個內嵌三角形組成初步之纏繞圖

待續

# 畫圓內N個正三角形之內嵌圖

畫圓內N個正三角形之內嵌圖_6個不重疊_20221207
畫圓內N個正三角形之內嵌圖_6個不重疊_20221207.png

畫圓內N個正三角形之內嵌圖_12個部分重疊_20221207

畫圓內N個正三角形之內嵌圖_12個部分重疊_20221207
程式碼:

# Python 畫內嵌正多邊形, 封裝成函數, 畫禪繞圖
# 20221207 By Peng-Jen Lai MATH NKNU
# 畫圓內N個正三角形之內嵌圖
# Python 畫內嵌正多邊形_禪繞_circleNRegTriangle_20221207.py

import math  
import turtle 
T=turtle.Turtle()
T.penup()
#startPoint=(-200,-200)
startPoint=(0,0)
#T.goto(-200,-200)
T.goto(startPoint)
T.pendown()
T.shape("turtle")
T.color("green")
T.pencolor("yellow")
T.turtlesize(1)
turtle.bgcolor("black") 
T.pensize(1)
T.speed(0)

def polygon(n, sideLength):
    for i in range(n):
        T.fd(sideLength)
        T.lt(360.0/n)

def imbededRegPoly(n=3, length=500, imbededNumber=5, alpha=0.1):
    beta=(n-2)/n*math.pi
    c=length

    for i in range(imbededNumber):
        polygon(n,c)

        a=c*alpha
        b=c*(1-alpha)
        beta=(n-2)/n*math.pi
        c=c*math.sqrt(alpha**2+(1-alpha)**2-2*alpha*(1-alpha)*math.cos(beta) )
        theta=math.asin(a/c*math.sin(beta))
        T.fd(a)
        T.lt(theta*180/math.pi)


#length=500

##########################

def circleNRegTirangle(N=6, radius=500, imbededNumber=10, alpha=0.1):
    """
    N is the inscribed N-regular polygon

    """
    angle = 0
    turnAngle = 2*180/N
    for i in range(N):
        T.penup()
        T.goto(startPoint)
        T.pendown()
        T.setheading(0)
        T.lt(angle)
        imbededRegPoly(n=3, length=radius, imbededNumber=imbededNumber, alpha=alpha)
        angle = angle + turnAngle


circleNRegTirangle(N=6, radius=250)

################################################
# 以下進行分解動作畫圓內6個三角形, 呼叫 imbededRegPoly 6次

##angle = 0
##for i in range(6):
##    T.penup()
##    T.goto(startPoint)
##    T.pendown()
##    T.setheading(0)
##    T.lt(angle)
##    imbededRegPoly()
##    angle = angle + 60

#############################################

Reference

  • 需要多隻海龜同時移動的方法, 可以參考
    從 Logo 海龜繪圖 學習 Python - 高中彈性課程系列 1 課程簡介, sec 各項提示或補充之總表
    https://editor.csdn.net/md/?articleId=107502070 link)

  • 以下這份影片的圖形與本篇的很多類似, 但是他沒有提供程式碼: https://youtu.be/hPsjMTz-aDQ link.

  • 以 Python重寫 MIT pythonTturtle Log 圖 與 河西朝雄C語言書中 的海龜繪圖圖形https://download.csdn.net/download/m0_47985483/87032053 link

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值