"考級"繪圖 40 例、函數定義、函數泛化、圖形變換、processing、turtle

2021-02-24 少兒創客幫
"考級"繪圖 40 例、函數定義、函數泛化、圖形變換、processing、turtle

後知後覺發現了繪圖等級考試 40 關的圖。


如何看待這些圖?

代碼實現

版本 1

版本 2

平移並旋轉

平移

正多邊形

正方形函數的泛化

旋轉 2 :不規則圖形的旋轉

對稱和旋轉

總結




我拿到的這個圖並沒有粗細、顏色、填充的變化,所以我不考慮這部分內容。

如何看待這些圖?logo 和 processing


logo 語言本身並不是作為專門的繪圖庫開發的,而是希望為利用計算機學習提供一個可以探索的環境,作為繼承者的 turtle 也不是專門為了繪圖開發的,雖然可以繪製各種幾何圖形。

利用 turtle 繪圖,更多的是從運動的觀點描述圖形,比如繪製正方形一般是前進特定距離,旋轉 90°,重複四次得到正方形,需要學生理解正方形四條邊相等、每個角都是 90° 的概念。我們也可以用另外的方式描述正方形:


這三種觀點對於圖形的認識相對而言比重複四次前進、旋轉的方法更加抽象。某種程度上, turtle  的設計初衷與編程基礎的學習,是不完全重合的。從繪圖的角度,我們既可以以運動的觀點來看到這 40 幅圖,也可以以靜止的觀點來描述。這取決於你面對的那種類型的初學者。

小學數學中涉及到了方格中的圖形變換(平移、旋轉、對稱、縮放),這是相對基礎的變換。就 turtle 本身而言,並沒有一個足夠的工具來描述圖形的變換。


比如,在 turtle 中繪製兩個正方形很容易,但是要表達右側圖形是左側圖形平移之後的結果,就比較困難。scratch 亦然。

但是 processing 及其衍生品中是有這樣的工具的,比如 pushMatrix 和 popMatrix ,用這個工具,可以非常簡單的對簡單圖形、複合圖形進行變換。

rect(0, 0, 100, 100);
pushMatrix();
translate(200, 0);  // 表示水平方向平移 200 像素
popMatrix();


processing  作為專業的繪圖庫、語言提供了豐富的繪圖功能和開箱即用的工具,降低了繪圖的門檻。當我看到這 40 張圖的時候,我首先想到的就是用 processing 的思維方式來繪製。這就需要把 processing 提供的工具,有限的遷移到 turtle 中,簡單的說就是對 turtle 進行二次開發,這麼說有點嚇人,或者說在 turtle 的基礎上定義一些函數,對 processing 的繪圖方式進行模仿,如果是用圖形化程式語言繪製,同樣的思路,圖形化程式語言,可以考慮編程貓的源碼編輯器,相比於 scratch ,提供了更加友好的編程調試體驗,可以在積木塊附近直接給出錯誤提示,降低了代碼調試的難度,避免學生限於錯誤中,找不到解決方案,從而產生沮喪的心理。即便是我自己,寫程序中卡住,也是一個相對負面的體驗。

分析圖


從基本圖形和圖形變換的角度來考慮這些圖形。

基本圖形


基本圖形:矩形(正方形),正多邊形(正三角形、四邊形、N 邊型)
圖形變換:旋轉。

複雜一點的圖形可能涉及到多種基本圖形的旋轉。

那麼我們可以定義函數完成這些任務,這就涉及到函數(子程序、自定義命令/積木)的知識。其實自定義函數(命令)很容易理解。劍術中最基本的動作是持劍,然後是基本劍術動作(劈、砍、刺、撩、雲),基本動作可以組合成招式(招包含式,比如推窗望月等),然後是套路,不同的套路其實可能包含相同的招式,前後左右有不同。API 或者 第三方庫也是如此。

在 turtle 和 scratch 中,其實可以按照如下對圖形進行分類:


多邊形可以看做是一些列點連接起來構成的圖形,對於正多邊形,也可以看做小烏龜或者角色前進、旋轉的重複。

turtle 中並未單獨定義 line 函數,移動函數,我們需要自行定義。

上面的這些圖中,涉及的變化,其實只有一種旋轉。只要找到基礎圖形,就可以繪製出這些圖形了。只要我們堅持每次繪製完基礎圖形(我們可以稱之為圖元),回到最初始的狀態,就可以用利用 lt 和 rt 實現圖形的旋轉,不需要單獨定義 pushMatrix (因為難,哈哈哈哈)。所以 40 圖中,後面的一些圖,本質上,是同一種圖,不過是基礎圖元的不同而已,這個時候考察的就不是編程的技巧了,而是觀察能力,和找出圖形中的基本圖形的能力。


而且 40 圖的設計,前面的幾個圖形,後面是會用到的。34 其實跟 5 有一點差別,但是類似。

自己定義函數的過程,是考察對於將基礎命令組合成複雜命令也就是命令抽象、過程的抽象,只要能定義出來,這些圖就可以繪製了。當然可以定義一個長方形函數 rect 正方形函數 square ,但是這些只是語法糖,本質上,在 square 內部可以調用 rect 完成繪製,在  rect  內部則調用 polyon (繪製多邊形),這個涉及到 泛化 的概念,從 square 到 rect 功能更加廣泛,所以可以看做是功能的泛化,就像 python 中並沒有平方函數,有的只是 math 模塊中的 pow 函數, pow 函數第二個參數是 2 就是平方。

代碼實現版本 1
from turtle import *

speed(0)


def move(x, y=None):
    """
    移動畫筆
    40 圖中其實用不太到
    """
    if not y and len(x) == 2:
        x, y = x
    pu()
    goto(x, y)


def line_to(x, y):
    """
    繪製多邊形邊用到
    """
    pd()
    goto(x, y)


def polyon(points: list):
    start_point = points[0]
    move(start_point)
    points.append(start_point)
    for point in points:
        if len(point) != 2:
            raise('坐標需要有兩個參數')
        x, y = point
        line_to(x, y)


def rect(x, y, w, h):
    """
    效果等同於
    for i in range(2):
        fd(w)
        rt(90)
        fd(h)
        rt(90)
    給學生講,這種方法更簡單
    """
    points = []
    points.append((x, y))
    points.append((x+w, y))
    points.append((x+w, y-h))
    points.append((x, y-h))
    polyon(points)


def square(x, y, w):
    rect(x, y, w, w)


square(0, 0, 100)

rect(-100, 100, 200, 200)

done()


這個版本實現了矩形繪製的泛化,但是需要指定左上角頂點和邊長,圖形旋轉的繪製對於學生會困難,因為無法計算矩形頂點坐標,所以這樣不合適。

版本 2
from turtle import *

speed(0)


def move(x, y=None):
    """
    移動畫筆
    40 圖中其實用不太到
    """
    if not y and type(x) == 'tuple':
        x, y = x
    pu()
    goto(x, y)


def line_to(x, y):
    """
    繪製多邊形邊用到
    """
    pd()
    goto(x, y)


def regular_polyon(start_point, side_length, sides: int):
    """
    start_points: 起點
    sides: 邊數
    """
    move(start_point)
    pd()
    for i in range(sides):
        fd(side_length)
        lt(360//sides)


def rect(x, y, w, h):
    move(x, y)
    pd()
    for i in range(2):
        fd(w)
        lt(90)
        fd(h)
        lt(90)


def square(x, y, w):
    # rect(x, y, w, w)
    regular_polyon((x, y), w, 4)


def flower(count=3, func=None, *args):
    """
    繪製繁花,無需給學生講,可以直接繪製
    """
    if not func:
        return
    for i in range(count):
        func(*args)
        rt(360//count)


square(20, 0, 100)

rect(-100, 100, 200, 200)
flower(3, square, 100, 0, 100)
flower(6, rect, 0, -100, 20, 100)


done()


def flower(count=3, func=None, *args):
    """
    繪製繁花,無需給學生講,可以直接繪製
    """
    if not func:
        return
    for i in range(count):
        func(*args)
        rt(360//count)

*args 的作用,是記錄關鍵字參數之後的所有參數,並原封不動的作為繪圖函數 func 的參數。這樣 flower 函數就泛化成了,繪製任意瓣數任意圖形的繁花函數,將函數作為參數的函數是高階函數,將命令作為參數,當然 scratch  和 源碼編輯器 都是不支持把函數作為參數的,但是,可以定義繪製特定繁花圖案的函數。或者把函數體拿出來就好了。

這裡 func 就是繪製基本圖元的函數了。

對於圖形 20,繪製的代碼就是:

# Figura 20
flower(5, square, 0, 0, 200)

這裡很多圖案,在 code.org 中的繪圖課程中都有所涉及的。

# Figura 30
flower(6, regular_polyon, (0, 0), 90, 6)



反而 Figura 14 需要動動腦筋,我畫的每個邊生成正三角形,原圖是直角三角形。


side_length = 210
third = side_length // 3

angles = [0, 45, -90, 45]
for i in range(4):
    for angle in angles:
        lt(angle)
        fd(third)
    rt(90)

這個圖形其實跟科赫雪花的繪製是類似的。


Figura 14

from math import pow
speed(1)
def figura_14(w):
    lt(45)
    l = w * pow(2, 0.5) / 2
    # l = w * 0.7
    pu()
    fd(l)
    pd()
    rt(135)
    # fd(w)
    third = w//3
    angles = [0, 45, -90, 45]
    for angle in angles:
        lt(angle)
        fd(third)
    rt(135)
    pu()
    fd(l)
    pd()
    rt(135)

# figura_14(120)


flower(4, figura_14, 120)


Figura 14 也可以像上面那麼畫,不過相對來說,代碼複雜了很多。

平移並旋轉image.png平移Figura 8

兩個正方形的平移。

square(0, 0, 200)
square(-100, 100, 200)

可以看到,在前面定義的 API 的基礎上,繪製 40 圖中的圖案變得簡單了許多。

# Figura 6
square(0, 0, 200)
square(20, -20, 160)

image.png正多邊形

Figura 1/9/10/11/12/13/15 都是正多邊形,用 regular_polyon 函數繪製即可。

其中 Figura 13 是圓,也可以用 turtle 庫的 circle 函數, circle 函數的實現其實也是用正多邊形模擬圓。

正方形函數的泛化


前文提到過,給定中心點和邊長可以界定矩形。processing 中,繪製矩形有 CORNER 模式和 CENTER 模式,對於 Figura 6  來說,屬於中心對稱圖形,所以我們也可以用正方形的中心點模式繪製。

def square(x, y, w, mode='conner'):
    # rect(x, y, w, w) square  也可以基於 rect 函數實現
    if mode == 'center':
        x -= w/2
        y += w/2
    regular_polyon((x, y), w, 4)


square(0, 0, 400, 'center')
square(0, 0, 420, 'center')

當然了,泛化的 square 函數的實現其實並不完善,但是作為 demo 使用足夠了。Figura 7 在 processing 中是可以用 CENTER 模式繪製的,背後的實現略複雜,這裡不寫了。

像 Figura 22 看上去很複雜,其實調用 flower 函數可以直接繪製。

旋轉 2 :不規則圖形的旋轉image.png

不規則圖形的旋轉,可以解釋為,flash 中的元件圍繞不同的中心點旋轉,Scratch 也有中心點的概念,涉及到這種圖形,只要在 Scratch 中設計正確的中心點,用 Scratch 中的旋轉 + 印章就可以繪製了。turtle 中也有 stamp函數,只要把烏龜的形狀設置為不規則圖形就可以了,這是另外一種系統的畫法了,代碼實現起來比用 regular_polyon 簡單的多,需要理解 turtle 的 addShape 函數,這需要單獨另外寫一篇文章了。

# 圖 4
def figura_4(x=0, y=0, side=80):
    """
    需要注意的是 x, y 是繪製的起點
    也就是 flash 和 Scratch 中的
    中心點
    """
    move(x, y)
    pd()
    fd(side)
    lt(90)
    fd(side/8)
    lt(90)
    fd(side-side/8)
    rt(90)
    fd(side-side*2/8)
    rt(90)
    fd(side-side/8)
    lt(90)
    fd(side/8)
    lt(90)
    fd(side)
    lt(90)
    fd(side)
    lt(90)

注意 figura_4 的函數定義中使用了默認值參數,這樣在不指定尺寸的時候,調用 flower 函數的代碼中更加簡潔。

# 在圖 4 的基礎上繪製圖 18
flower(4, figura_4)

image.png
from random import randint

for i in range(-20, 20, 1):
    SIZE = 32
    x = i // 4 * SIZE * 2 + SIZE / 2
    y = i % 4 * SIZE * 2 + SIZE / 2
    flower(4, figura_4, x, y, SIZE)

image.png
from random import randint

for i in range(-20, 20, 1):
    SIZE = 32
    angle = randint(0, 360)
    rt(angle)
    x = i // 4 * SIZE * 2 + SIZE / 2
    y = i % 4 * SIZE * 2 + SIZE / 2
    flower(4, figura_4, x, y, SIZE)

image.png
from random import randint

for i in range(-20, 20, 1):
    SIZE = randint(8, 32)
    angle = randint(0, 360)
    rt(angle)
    x = i // 4 * SIZE * 2 + SIZE / 2
    y = i % 4 * SIZE * 2 + SIZE / 2
    flower(4, figura_4, x, y, SIZE)

由於定義了 flower 函數,所以,其他圖形也可以用這種方式繪製。



這個圖跟圖 4 是有關聯的。

對稱和旋轉


圖 3 到 圖 37 有所縮放,並且中心點也不同,所以有點不是很好理解。雖然 turtle 提供了切變函數,但是對於小學生來說並不好理解。

圖 27 其實也是 圖 5 變化而來,只不過繪製的起始點不同。** 小烏龜從哪個點開始繪製,哪個點就是中心點** 。

總結

不想寫了。。。。
反正就是:

圖 40 前面的幾個簡單的圖是後面圖的基本圖形(圖元)可以參考 processing 自定義繪製圖形的函數,再次基礎上定義高階函數 flower 簡化由旋轉得來的圖形的繪製繪製基本圖形的函數可以從不同的點開始畫,並旋轉不同次數,得到不同的圖案其實原本的主旨是函數的定義,抽象,用簡單的命令構建複雜的系統。比如我在 fd 等基礎上構建了 square ,在 square 的基礎上構建了 flower,增強了 turtle 的表達能力,從而實現一行代碼繪製由基本圖形旋轉得到的圖案繪製這些圖形並不需要複雜的 python 基礎知識

相關焦點

  • 【Python教程】圖形界面 ——海龜繪圖
    )在屏幕上繪圖。海龜繪圖(Turtle Graphics)後來被移植到各種高級語言中,Python內置了turtle庫,基本上100%複製了原始的Turtle Graphics的所有功能。調用width()函數可以設置筆刷寬度,調用pencolor()函數可以設置顏色。更多操作請參考turtle庫的說明。繪圖完成後,記得調用done()函數,讓窗口進入消息循環,等待被關閉。否則,由於Python進程會立刻結束,將導致窗口被立刻關閉。turtle包本身只是一個繪圖庫,但是配合Python代碼,就可以繪製各種複雜的圖形。
  • 149 指數函數的定義、性質與圖形-----圖形的奧妙
    上一節「148 冪函數的圖形」介紹了冪函數的定義、性質和圖形。指數函數的嚴格定義使該函數變得又單純又經典。三、指數函數的圖形由於α≠1,指數函數的圖形要分為0<α<1和α>1兩種情況討論。1、0<α<1  如函數y=(1/2)^x,0<(1/2)<1,其圖形如下。
  • 只要十分鐘,python繪圖神器turtle了解一下?
    turtle繪圖窗體布局畫布就是turtle為我們展開用於繪圖區域setup函數不是必須的,只有當需要控制繪圖窗體大小的時候才調用。import turtleturtle.begin_fill() #開始填充turtle.color("red") #填充黑色turtle.circle(40)turtle.end_fill
  • Python中的畫圖神器turtle
    簡介turtle庫是python的繪圖庫,利用turtle可以製作很多複雜的繪圖。
  • Python turtle 繪圖入門必知必會
    Turtle庫是Python語言中一個簡單流行的繪圖函數庫(叫做海龜繪圖Turtle Graphics),Turtle庫是Python的內部庫,
  • Processing入門教程第二課——基礎圖形
    並且我們簡單的編寫了一個我們的第一個程序「hello,world」和真正的processing特點的程序。那麼從這一篇文章開始我們開始真正的學習Processing.    學習Processing的第一步當然是最基礎的畫圖,雖然Processing當中2D繪畫和3D繪畫差不太多但是我們先從2D圖形開始學起比較好。
  • 傅立葉變換繪製二維圖形|小記
    傅立葉變換繪製二維圖形|小記 2019-09-26 14:36 來源:澎湃新聞·澎湃號·湃客
  • R語言簡介、安裝、R包的安裝問題、R的繪圖函數概覽、par()函數及plot()函數詳解
    R有哪些繪圖包及周邊函數、周邊參數    基礎繪圖包在R被安裝後就存在,ggplot2、maps等高級繪圖包需要額外安裝和加載。    基礎繪圖包包括:高級繪圖函數和低級繪圖函數,而par()函數是專門用來為基礎繪圖包設置繪圖參數的函數。
  • 教你用python畫圖—Turtle詳細教程
    在Python中,使用turtle模塊的幾行代碼、改變幾個參數就能繪出漂亮的圖形,如果再增加一些參數,還能繪製出如笑臉、哆啦A夢、表情包等創意十足的圖像,令人驚嘆。在學著繪圖時,就會逐步學習python的一些基本語法、函數、模塊、類和對象等基礎知識;邊玩邊學四字成語非常恰當的描述了玩轉turtle模塊的境界,也非常適宜於少兒或者初學者進入Python的世界。
  • 函數的基本性質知識點的總結——期末必考的內容
    ⑴定義法定義法是根據函數的增函數和減函數的定義的方法來判斷函數的單調性的方法。設函數f(x)定義域內的兩個值為x1,x2,當x1<x2時,判斷f(x1)和f(x2)大小。函數的奇偶性⑴判斷函數的奇偶性的步驟:第一步,判斷函數f(x)的定義域是否關於原點對稱。如果該定義域不關於原點對稱,則函數f(x)是非奇非偶函數;如果該定義域關於原點對稱,則進行下一步的判斷。
  • C++之函數模板的概念和意義
    一、函數模板的引出:1、c++中有幾種交換變量的方法:(1)定義宏代碼塊(2)定義函數代碼版本一:#include <iostream>#include <string>using namespace
  • Turtle可以輕鬆解決
    Turtle模塊絕對是吸引非專業代碼開發者學習Python入門的好工具,通過turtle幾行代碼的執行軟體就會畫出漂亮的圖形,美觀而且有成就感。這些漂亮的圖形如三角形、五角星、機器貓等。在寫代碼的時候改變幾個參數,就可以產生新的奇怪形狀。那今天我們看看如何用Python語言裡turtle模塊編寫動態萬年曆吧!
  • 寫給設計師的 Processing 編程指南(13) - 3D繪圖
    在學習新的知識點前,希望你已經在二維繪圖上足夠嫻熟。用代碼在三維空間繪圖,與 3dMax ,Maya 這類三維軟體相比,有完全不一樣的體驗。由於裡面沒有直觀的界面來控制和調整物體的位置,所以寫起來會比較抽象。其中有一難點,要熟悉空間坐標系以及對應的各種變換操作。在平面上繪圖只需考慮兩個維度,x 軸和 y 軸。但在三維空間中,會多出一個 z 軸。
  • 「Turtle繪圖」Python基礎課程 turtle繪圖(一)
    膠州六中賢紀玲老師教授了《Python基礎課程 turtle繪圖(一)》人工智慧課。本節課的課程目標:一是認識turtle(海龜)繪圖,並熟記一些簡單的程序代碼。二是結合turtle(海龜)繪圖進行簡單圖形的繪製。首先,賢老師通過欣賞一個用turtle(海龜)製作的動態圖形來激發孩子們的興趣,引出課題《Python基礎課程 turtle繪圖》。
  • MATLAB的ezplot函數繪製隱函數圖像
    2、ezplot函數ezplot是畫出隱函數圖形,是形如f(x,y)=0這種不能寫出像y=f(x)這種函數的圖形ezplot一元函數繪圖函數ezplot(fun) ezplot(fun,[min,max])函數ezplot它無需數據準備,直接畫出函數圖形,基本調用格式為ezplot(f),其中f 是字符串或代表數學函數的符號表達式
  • R語言之plot繪圖函數的使用
    R有強大的繪圖功能,plot()函數是一種常用的繪圖函數,用其可以繪製散點圖、曲線圖等。plot函數的語法格式R語言中plot()函數的基本格式如下:plot(x,y,...)plot函數中,x和y分別表示所繪圖形的橫坐標和縱坐標;函數中的...為附加的參數。
  • Python編程11:Python畫圖之turtle模塊
    turtle模塊繪圖思路首先導入turtle模塊;起始默認位置被設定在(0,0)處,即窗口的中心(起始位置可以設置),且繪製方向是從左往右;turtle模塊是模擬用筆繪製圖形的,默認筆是向下的(turtle.pendown()),好像筆尖放在紙上一樣;開始畫圖時,設置筆向下,按照要求移動繪製圖形繪製結束,將筆抬起turtle.penup()【練習1】畫直線
  • 考生須知及EXCEL常用函數_計算機二級必備!!
    從字符 s 開始,檢索出字符 A   2.字符串長度檢測函數:Len(<字符串表達式>或<變量名>) 返回字符串所含字符數。注意,定長字符,其長度是定義時的長 度,和字符串實際值無關。
  • python的繪圖利器--海龜繪圖turtle
    這個語句是個固定格式,有這句話畫完圖,繪圖窗口還保留,如果沒有這句話,繪圖窗口就直接關閉了,所以初期都加上就好了。turtle是一個專門用於繪圖的庫,需要畫圖的時候我們直接import一下就好,在此需要說明的有兩點:其他庫也一樣,直接import一下就好,例如:pyquery 網頁解析庫, pymysql 存儲庫等等。
  • [專題]在Python教學中應用turtle創意編程實踐
    Python語言自帶的turtle繪圖包,情景來源是小海龜在海灘上爬行,尾巴在沙灘上拖出線條。利用turtle畫圖具有logo語言的特徵,很適合創意編程。這是因為它有以下特點。●首先是實現簡單。只需要少量函數就可以完整實現平面上繪圖的功能,學習的門檻低。●其次是環境依賴小。只要安裝了Python語言,就自帶了turtle庫,而且不用設置,默認就可以用。