φυβλαςのβλογ
phyblas的博客



[python] สร้างแฟร็กทัลอย่างง่าย
เขียนเมื่อ 2017/02/23 20:06
แก้ไขล่าสุด 2024/02/22 10:57
บางคนอาจไม่คิดมาก่อนว่าการเขียนโปรแกรมกับศิลปะจะไปด้วยกันได้ แต่จริงๆแล้วการเขียนโปรแกรมเป็นวิธีการในการสร้างสรรค์งานศิลปะได้ดีมากอย่างหนึ่งเลยทีเดียว

วันนี้จะมาแนะนำสิ่งที่เรียกว่า "แฟร็กทัล" (fractal)

คำอธิบายเกี่ยวกับแฟร็กทัลอ่านได้ในวิกิ https://th.wikipedia.org/wiki/แฟร็กทัล

พูดง่ายๆก็คืออะไรบางอย่างที่มีรูปแบบวนซ้ำโดยเพิ่มจำนวนขึ้นและเล็กลงเรื่อยๆ เหมือนอย่างต้นไม้แตกกิ่ง, เซลล์แบ่งตัว, เกล็ดหิมะ, ฯลฯ

ในธรรมชาติมีหลายสิ่งหลายอย่างที่มีลักษณะของแฟร็กทัล ซึ่งทำให้ดูแล้วสวยงาม

ในบทความนี้จะมาลองใช้ภาษาไพธอนสร้างงานศิลปะในรูปแบบของแฟร็กทัลขึ้นมา

การเขียนโปรแกรมเพื่อสร้างแฟร็กทัลขึ้นนั้นนิยมใช้ฟังก์ชันเวียนเกิด ใครยังไม่เข้าใจว่าหมายถึงอะไรสามารถทำความเข้าใจได้ในเนื้อหาไพธอนเบื้องต้นบทที่ ๒๐ ซึ่งได้อธิบายไว้

อธิบายด้วยคำพูดนั้นเป็นเรื่องยาก ดังนั้นขอยกโค้ดฟังก์ชันที่ใช้สร้างแฟร็กทัลมาเลย
import numpy as np

def fractal(n):
    if(n>0):
        x,y = fractal(n-1)
        for i in range(len(x)):
            for j in range(5):
                theta = (x[i]+j*2)/5*np.pi
                r = (y[i]+1)/2
                x += [r*np.cos(theta)]
                y += [r*np.sin(theta)]
        return x,y
    else:
        theta = np.radians(np.arange(361))
        x = [np.cos(theta)]
        y = [np.sin(theta)]
        return x,y

ฟังก์ชันนี้จะให้ค่า x,y ซึ่งเป็นลิสต์ของจุดของเส้นที่เป็นส่วนประกอบของของแฟร็กทัล

ค่า n ที่ต้องใส่ให้กับฟังก์ชันก็คือจำนวนชั้นของแฟร็กทัลที่ต้องการวาด

ผลค่า x,y ที่ได้จะนำมาวาดเป็นภาพใน matplotlib เพื่อแสดงภาพให้เห็นได้ ลองสร้างฟังก์ชันสำหรับวาดไว้ตามนี้
import matplotlib.pyplot as plt

def plot_fractal(n):
    x,y = fractal(n)
    plt.figure(figsize=[10,10])
    plt.axes([0,0,1,1],xlim=[-1,1],ylim=[-1,1],aspect=1,axis_bgcolor=[0,0,0])
    si = plt.get_cmap('rainbow')(np.random.rand(len(x)))
    for i in range(len(x)):
        plt.plot(x[i],y[i],color=si[i])
    plt.show()

ในนี้ใช้คัลเลอร์แม็ปแค่เพื่อให้แต่ละเส้นถูกวาดด้วยสีต่างๆกันไปแบบสุ่มจะได้เห็นชัดและสวยขึ้น

เริ่มแรกใส่
plot_fractal(0)



จะเห็นว่าออกมาเป็นวงกลมวงเดียวธรรมดา ซึ่งก็ไม่แปลกเพราะเมื่อใส่ค่า 0 จะเข้าเงื่อนไข else ด้านล่าง ซึ่งเป็นการสร้างวงกลมขึ้นมาอันหนึ่งเฉยๆอย่างที่เห็น

จากนั้นจะเป็นยังไงถ้าใส่ plot_fractal(1)

ผลที่ได้ก็จะเห็นว่ามีวงเล็กโผล่เข้ามาด้านในอีก ๕ อัน



จากฟังก์ชันจะเห็นได้ว่าพอ n>0 ก็จะเข้าเงื่อนไขบน ซึ่งเริ่มมาถึงมันจะไปเรียกใช้ตัวมันเองที่มีลำดับขั้นต่ำลง (ใช้ n-1) ซึ่งเป็นลักษณะของการเวียนเกิดนั่นเอง ในที่นี้ fractal(0) จะถูกเรียกขึ้นมาแล้วให้เส้นวงกลม

แต่เส้นวงกลมนั้นจะถูกนำไปสร้างเป็นวงกลมย่อยห้าอัน สุดท้ายก็จะได้เส้นวงกลมเพิ่มมาอีก ๕ อัน รวมอันเดิมก็เป็น ๖ อัน จึงเกิดวงใหญ่และวงย่อยตามที่เห็น

จากนั้นถ้าลอง plot_fractal(2) ก็จะออกมาเป็นแบบนี้



เรื่องราวจะซับซ้อนขึ้นไปอีกขั้น แต่สรุปง่ายๆก็คือจะมีเส้นวง ๕ วงเพิ่มเข้ามาในแต่ละวงย่อย

ที่จะสังเกตได้ก็คือใน fractal(2) จะมีการเรียก fractal(1) ไป ๕ ครั้ง และใน fractal(1) แต่ละครั้งก็จะเรียก fractal(0) ๕ ครั้ง ดังนั้นรวมแล้วฟังก์ชันถูกเรียกทั้งหมด 5*5+5+1 = 5**2+5**1+5**0 ครั้ง

ในแต่ละครั้งที่เรียกก็เป็นการสร้างเส้นวงย่อยไปเรื่อยๆ

ถ้าเพิ่มเลขไปเรื่อยๆ ก็จะยิ่งซับซ้อนมากขึ้น และจำนวนเส้นก็เพิ่มมากเป็นเลขยกกำลัง โปรแกรมยิ่งทำงานนานขึ้นอย่างเห็นได้ชัด

ลอง plot_fractal(3)



plot_fractal(4)



plot_fractal(5)



ไล่มาจนถึงตอนนี้ น่าจะทำให้เห็นภาพรวมและเข้าใจได้ไม่มากก็น้อย

นี่เป็นตัวอย่างแฟร็กทัลแบบง่ายๆแบบหนึ่งเท่านั้น ถือว่าไม่ซับซ้อน สามารถหาตัวอย่างอื่นๆที่ซับซ้อนได้ที่อื่นอีกมากมาย

หากเอามาปรับแต่งทำอะไรดีๆสามารถเป็นงานศิลปะได้สบาย

ตัวอย่างงานที่ประยุกต์เอาแฟร็กทัลมาเป็นส่วนประกอบ เช่นลองเปลี่ยนจาก ๕ แฉก เป็น ๘ แฉก แล้ว แล้วปรับอะไรอีกหน่อย



ลองทำเป็นรูปแบบคล้ายๆดอกไม้ดูก็ได้



ส่วนรูปต่อไปอันนี้ทำขึ้นมาโดยการลองเขียนโค้ดแล้วปรับแต่งค่าต่างๆแล้วก็เพิ่มอะไรๆแล้วดูไปเรื่อยๆจนได้ลักษณะที่คิดว่าออกมาสวยดี โค้ดที่ใช้วาดค่อนข้างเละเทะจึงไม่ขอนำมาลงในนี้ แต่หากเข้าใจหลักการแล้วการทำแบบนี้ออกมาก็ไม่ยาก



ลองเอามาใส่เป็นลายของร่มกระดาษน้ำมันจีน ดูแล้วสวยดี



(ภาพนี้สร้างในโปรแกรมมายา ส่วนร่มนั้นสร้างด้วยโค้ดไพธอนดังที่เขียนไปใน https://phyblas.hinaboshi.com/20170220)



ใครอยากลองสร้างแฟร็กทัลอาจลองเขียนโค้ดดูได้ หรือไม่ก็จะใช้โปรแกรมสำเร็จรูปก็ได้ ปัจจุบันมีโปรแกรมมากมายที่ใช้สร้างแฟร็กทัลขึ้นมา

หากอยากดูงานศิลปะที่สร้างจากแฟร็กทัลสามารถค้น google ดูกันต่อได้


-----------------------------------------

囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧

ดูสถิติของหน้านี้

หมวดหมู่

-- คอมพิวเตอร์ >> เขียนโปรแกรม >> python >> numpy
-- คอมพิวเตอร์ >> เขียนโปรแกรม >> python >> matplotlib

ไม่อนุญาตให้นำเนื้อหาของบทความไปลงที่อื่นโดยไม่ได้ขออนุญาตโดยเด็ดขาด หากต้องการนำบางส่วนไปลงสามารถทำได้โดยต้องไม่ใช่การก๊อปแปะแต่ให้เปลี่ยนคำพูดเป็นของตัวเอง หรือไม่ก็เขียนในลักษณะการยกข้อความอ้างอิง และไม่ว่ากรณีไหนก็ตาม ต้องให้เครดิตพร้อมใส่ลิงก์ของทุกบทความที่มีการใช้เนื้อหาเสมอ

目录

从日本来的名言
模块
-- numpy
-- matplotlib

-- pandas
-- manim
-- opencv
-- pyqt
-- pytorch
机器学习
-- 神经网络
javascript
蒙古语
语言学
maya
概率论
与日本相关的日记
与中国相关的日记
-- 与北京相关的日记
-- 与香港相关的日记
-- 与澳门相关的日记
与台湾相关的日记
与北欧相关的日记
与其他国家相关的日记
qiita
其他日志

按类别分日志



ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ

  查看日志

  推荐日志

ตัวอักษรกรีกและเปรียบเทียบการใช้งานในภาษากรีกโบราณและกรีกสมัยใหม่
ที่มาของอักษรไทยและความเกี่ยวพันกับอักษรอื่นๆในตระกูลอักษรพราหมี
การสร้างแบบจำลองสามมิติเป็นไฟล์ .obj วิธีการอย่างง่ายที่ไม่ว่าใครก็ลองทำได้ทันที
รวมรายชื่อนักร้องเพลงกวางตุ้ง
ภาษาจีนแบ่งเป็นสำเนียงอะไรบ้าง มีความแตกต่างกันมากแค่ไหน
ทำความเข้าใจระบอบประชาธิปไตยจากประวัติศาสตร์ความเป็นมา
เรียนรู้วิธีการใช้ regular expression (regex)
การใช้ unix shell เบื้องต้น ใน linux และ mac
g ในภาษาญี่ปุ่นออกเสียง "ก" หรือ "ง" กันแน่
ทำความรู้จักกับปัญญาประดิษฐ์และการเรียนรู้ของเครื่อง
ค้นพบระบบดาวเคราะห์ ๘ ดวง เบื้องหลังความสำเร็จคือปัญญาประดิษฐ์ (AI)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ