🗺️ What you will do on this page
First you learn the words, and what a fractal really is: a shape that repeats at every size, made by one short rule used again and again. Then you meet four fractals — and you can play with every one of them:
❄️ A snowflake
that grows spikes on its spikes, until its edge becomes infinitely long.
🌳 A tree
drawn with only four numbers you can change.
🔍 The Mandelbrot set
one line of maths you can zoom into forever.
🎲 A triangle
made only from random dots.
🔵 A geodesic dome
which looks like a fractal — but it is not. Finding out why is the real test.
Every section ends with a short quiz, so you can check yourself. Every section also has a 🔊 Listen button if you want to hear it instead of reading it.
每一节最后都有一个小测验,方便你随时自查;每一节也都有🔊 收听按钮,如果你更想听而不是读。
ทุกหัวข้อจบด้วยแบบทดสอบสั้นๆ และทุกหัวข้อมีปุ่ม 🔊 ฟัง ถ้าคุณอยากฟังมากกว่าอ่าน
📖 Key words — learn these first
Twelve words. Press Listen & Repeat and say each word out loud after the voice. Then try the speaking practice and see if the computer understands you. 先学这些词。
🤔 “Algorithm” and “fractal” are not the same word
People often mix these two words up, so let us be clear — they are not even the same kind of thing.
- An algorithm is a list of steps: you follow the steps, then you stop, and you have an answer. “Add these numbers.” “Sort this list.” A recipe and the instructions for building a table are both algorithms.
- A fractal is a shape: a pattern that looks the same at every size. It is something you look at, not a list of steps.
算法(algorithm,算法)是一套步骤:一串有限的步骤,你照做,然后停下来,手里拿着答案。"把这些数加起来。""把这个列表排序。"菜谱、长除法、组装家具的说明书,都是算法。
分形(fractal)是一个形状:一种在每个尺度上看起来都一样的图案。它是你可以看的东西,而不是一套指令。
อัลกอริทึม (algorithm) คือกระบวนการ: รายการขั้นตอนที่มีจำนวนจำกัด ทำตามแล้วหยุด พร้อมคำตอบในมือ "บวกเลขเหล่านี้" "เรียงรายการนี้" สูตรอาหาร การหารยาว และคู่มือประกอบเฟอร์นิเจอร์ ล้วนเป็นอัลกอริทึม
แฟร็กทัล (fractal) คือรูปทรง: ลวดลายที่หน้าตาเหมือนกันในทุกขนาด มันคือสิ่งที่คุณมองดูได้ ไม่ใช่ชุดคำสั่ง
🎯 Match them up
Tap an English word, then tap its meaning. 点一个英文词,再点它的意思。
Find all 12 pairs.
fractal 分形——在每个尺度上重复的形状;整个图案都活在每一个部分里
recursion 递归——一条用到自己的规则;一个小函数就能画出整棵树
base case 基准情形——递归规则里"到此为止"的那一部分;没有它,什么都无法结束
self-similar 自相似——小块看起来就像整体(一根树枝就是一棵小树)
iteration 迭代——"再来一次"的一轮;分形由成千上万次迭代构成
ratio 比例——两个尺寸的比较;2:1 表示一个是另一个的两倍
golden ratio 黄金比例——φ≈1.618;斐波那契数列稳定到的那个比例,艺术家也用它
algorithm 算法——一串有限的步骤,做完会停下来并给出答案——是食谱,不是蛋糕
🎯 配对练习:点一个英文单词,再点它的意思,把 8 对全部配好。
fractal แฟร็กทัล — รูปทรงที่ซ้ำในทุกขนาด ลวดลายทั้งหมดอยู่ในทุกส่วน
recursion การเรียกซ้ำ — กฎที่ใช้ตัวเอง วิธีที่ฟังก์ชันเล็กๆ วาดต้นไม้ทั้งต้น
base case กรณีฐาน — ส่วน "หยุดตรงนี้" ของกฎเรียกซ้ำ ถ้าไม่มี ก็ไม่มีอะไรจบ
self-similar คล้ายตัวเอง — ชิ้นเล็กหน้าตาเหมือนภาพรวม (กิ่งคือต้นไม้เล็ก)
iteration การวนซ้ำ — หนึ่งรอบของ "ทำอีกครั้ง" แฟร็กทัลสร้างจากมันหลายพันรอบ
ratio อัตราส่วน — การเทียบสองขนาด 2:1 คือหนึ่งเป็นสองเท่าของอีกอัน
golden ratio อัตราส่วนทองคำ — φ ≈ 1.618 อัตราส่วนที่ฟีโบนักชีนิ่งเข้าหา และศิลปินใช้สร้างงาน
algorithm อัลกอริทึม — รายการขั้นตอนที่มีจำกัด ทำแล้วจบพร้อมคำตอบ — เป็นสูตร ไม่ใช่ขนม
🎯 จับคู่: แตะคำอังกฤษ แล้วแตะความหมาย ให้ครบ 8 คู่
✓ Check yourself — the key words
🌿 Start here: what is a fractal?
Hold a fern leaf in your hand. It is made of smaller leaves — and each of those is made of even smaller leaves, the same shape all the way down. Break a branch off a tree and you are holding a little tree. Zoom in on a coastline and the bays are full of smaller bays, and those are full of smaller bays too. This is a fractal (分形): a shape that repeats at every size, so the whole pattern lives inside every part of it.
Here is the surprise. A fractal is not a big, difficult drawing that somebody worked on for a long time. It is one short rule, used again and again — usually a rule that uses itself. “Draw a line, then start two smaller trees at its tip.” “Move half-way to a random corner.” Each rule is short and easy to remember, but each one grows something nobody could draw by hand.
That is why nature is full of fractals, and why they are so useful. A seed is much too small to hold a map of every leaf the plant will grow — but it can easily hold a rule. Your lungs branch about 23 times, and this folds a surface as big as a tennis court inside your chest. Rivers, lightning, blood vessels, broccoli, clouds and mountains are all built the same cheap way: one instruction, repeated at smaller and smaller sizes.
Why is this idea important? Because it finally let mathematics describe the shapes of the real world. For three hundred years, geometry studied smooth, tidy things — lines, circles, spheres. These are perfect for planets, but almost useless for anything you can see out of a window. Nothing outdoors is smooth. Coastlines, clouds, tree bark, lungs, lightning and mountains are rough at every size. Before fractals, there was no good way to describe them or measure them. That is what you are learning here: the geometry of natural shapes, and a way of thinking that turns “complicated” into “one small rule, repeated”.
And once you can see it, the same few ratios appear again and again in very different places — in a tree, in a coastline, in a spiral, in a set of numbers. Everything on this page is a toy — change a number and watch what happens.
下面这一点会让所有人吃惊:分形不是某个人辛苦画出来的一幅巨大复杂的图,而是一条简短的规则,被反复遵守——而且通常是一条会引用自己的规则。"画一条线,然后在它的顶端长出两棵更小的树。""贴着长边加一个同样大的正方形。""朝随机的一个角走一半。"每一句都短得能记住,而每一句都能长出没有人能徒手画出的东西。
这就是为什么大自然里到处都是分形,也是它们如此有用的原因。一颗种子远远装不下"这株植物将来每一片叶子"的地图——但它很容易装下一条规则。你的肺分支约 23 次,把一个网球场的表面积折进胸腔。河流、闪电、血管、西兰花、云和山脊,都是用同样省事的方式造出来的:一条指令,在越来越小的尺度上重复。
那么为什么要专门用一页讲这个?因为正是这个观念,才终于让数学能够描述真实存在的那些形状。几何学花了三百年研究光滑、整齐的东西——直线、圆、球、有漂亮方程的曲线——它们对炮弹和行星堪称完美,对你从窗户看出去的任何东西却几乎无用。户外没有任何东西是光滑的。海岸线、云、树皮、肺、闪电和山脉,在每一个尺度上都是粗糙的、分叉的、皱褶的;在分形出现之前,我们没有恰当的办法去描述它们,更谈不上测量。这正是你在这里要学的:自然形状的几何学,以及一种把“复杂”变成“一条小规则,不断重复”的思考方式。
而一旦你能看见它,同样的少数几个比例就会不断出现在本该毫不相干的地方——在一棵树里、在一段海岸线里、在一条螺旋里、在一串数字里,以及在一个数学家至今仍在争论的形状里。这里的一切都是可以上手玩的——改一个数字,看看会发生什么。
ส่วนที่ทำให้ทุกคนประหลาดใจคือ: แฟร็กทัลไม่ใช่ภาพวาดขนาดใหญ่ที่ซับซ้อนซึ่งใครบางคนทุ่มเทวาด แต่เป็นกฎสั้นๆ ข้อเดียวที่ทำตามซ้ำแล้วซ้ำอีก — และมักเป็นกฎที่อ้างถึงตัวเอง "ลากเส้นหนึ่งเส้น แล้วเริ่มต้นไม้เล็กสองต้นที่ปลาย" "เพิ่มสี่เหลี่ยมขนาดเท่าด้านยาวของคุณ" "เคลื่อนไปครึ่งทางหามุมที่สุ่มได้" แต่ละประโยคสั้นพอที่จะจำได้ และแต่ละประโยคปลูกสิ่งที่ไม่มีใครวาดด้วยมือได้
นี่คือเหตุผลที่ธรรมชาติเต็มไปด้วยแฟร็กทัล และเหตุผลที่มันมีประโยชน์มาก เมล็ดพืชเล็กเกินกว่าจะเก็บแผนที่ของทุกใบที่ต้นไม้จะสร้างขึ้น — แต่เก็บกฎได้สบายๆ ปอดของคุณแตกกิ่งราว 23 ครั้งเพื่อพับพื้นที่ผิวขนาดสนามเทนนิสไว้ในอก แม่น้ำ ฟ้าแลบ หลอดเลือด บรอกโคลี เมฆ และสันเขา ล้วนสร้างด้วยวิธีประหยัดแบบเดียวกัน: คำสั่งเดียว ทำซ้ำในขนาดที่เล็กลงเรื่อยๆ
แล้วทำไมต้องใช้ทั้งหน้าเพื่อเรื่องนี้? เพราะนี่คือความคิดที่ทำให้คณิตศาสตร์อธิบายรูปทรงที่มีอยู่จริงได้เสียที เรขาคณิตใช้เวลาสามร้อยปีกับสิ่งที่เรียบและเป็นระเบียบ — เส้นตรง วงกลม ทรงกลม เส้นโค้งที่มีสมการสวยงาม — ซึ่งสมบูรณ์แบบสำหรับลูกกระสุนและดาวเคราะห์ และแทบไร้ประโยชน์กับอะไรก็ตามที่คุณเห็นนอกหน้าต่าง ไม่มีอะไรกลางแจ้งที่เรียบ แนวชายฝั่ง เมฆ เปลือกไม้ ปอด ฟ้าแลบ และภูเขา ล้วนขรุขระ แตกกิ่ง และย่นในทุกขนาด และก่อนจะมีแฟร็กทัล เราไม่มีวิธีอธิบายมันอย่างเหมาะสม ไม่ต้องพูดถึงการวัด นี่คือสิ่งที่คุณกำลังเรียน: เรขาคณิตของรูปทรงตามธรรมชาติ และวิธีคิดที่เปลี่ยน “ซับซ้อน” ให้เป็น “กฎเล็กๆ ข้อเดียว ทำซ้ำ”
และเมื่อคุณมองเห็นมันแล้ว อัตราส่วนไม่กี่ตัวเดิมจะปรากฏซ้ำในที่ที่ควรจะไม่เกี่ยวข้องกันเลย — ในต้นไม้ ในแนวชายฝั่ง ในเกลียว ในชุดตัวเลข และในรูปทรงที่นักคณิตศาสตร์ยังถกเถียงกันอยู่ ทุกอย่างที่นี่คือของเล่นที่หยิบจับได้ — เปลี่ยนตัวเลขแล้วดูว่ามันทำอะไร
🏞️ One valley, five times the same idea
Before the labs, here is a place to hold the idea. This is an imagined valley below Doi Suthep. Every picture below shows the same instruction, repeated at a different size. (用同一条规则盖出来的山谷)
Made at home on our own GPU — no cloud, no cost, no image leaving the house.
山谷:看那片树冠——一种树的形状,在每一个距离上重复,直到化成薄雾。没有人一棵一棵地画它们;这片森林是一条规则,跑了几百年。
蕨叶:每一片小叶都是整片叶子的缩小版,而每一片小叶又再分一次。掰下一片,你分不出自己放大了多少倍。
梯田:同一道弧线,随山坡逐级缩小;而水靠分叉找到它们,一条渠变两条、变四条、变一百条。
村落:同一栋房子的四种尺寸,沿坡而下,就像树枝沿着树干排列。有几何感,却是长出来的,不是规划出来的。
蘑菇屋:最古老的办法——盖一座,再盖一座小一点的,一路盖到山用完为止。
这些图都在我们自己的 GPU 上本地生成——不上云、零成本、图片不出这栋房子。
หุบเขา: ดูเรือนยอดไม้สิ — รูปทรงต้นไม้แบบเดียว ซ้ำในทุกระยะจนกลายเป็นหมอก ไม่มีใครวาดทีละต้น ป่าผืนนี้คือกฎข้อหนึ่งที่ทำงานมาหลายร้อยปี
ใบเฟิร์น: ใบย่อยทุกใบคือสำเนาย่อของใบทั้งใบ และแต่ละใบย่อยก็แตกย่อยอีก เด็ดมาหนึ่งใบแล้วคุณจะบอกไม่ได้ว่าซูมเข้าไปไกลแค่ไหน
นาขั้นบันได: เส้นโค้งเดียว ไล่ลงเขาทีละขั้นด้วยขนาดที่เล็กลง และน้ำหาทางไปถึงมันด้วยการแตกสาย จากหนึ่งเป็นสอง เป็นสี่ เป็นร้อย
หมู่บ้าน: บ้านหลังเดียวกันในสี่ขนาด วางไล่ลงเนินเหมือนกิ่งที่เรียงตามลำต้น เป็นเรขาคณิต แต่งอกขึ้นมาเอง ไม่ได้ถูกวางผัง
บ้านเห็ด: วิธีที่เก่าแก่ที่สุด — สร้างหนึ่งหลัง แล้วสร้างอีกหลังให้เล็กลง ไล่ขึ้นเขาไปจนกว่าเขาจะหมด
ภาพทั้งหมดเรนเดอร์บน GPU ของเราเอง — ไม่ใช้คลาวด์ ไม่มีค่าใช้จ่าย ไม่มีภาพไหนออกจากบ้านหลังนี้
📷 Real fractals — no computer, no drawing
The valley pictures above were made by a computer. These four are real photographs. Nature built every one of them the same way: one rule, repeated at smaller and smaller sizes. (真实照片里的分形)
✓ Check yourself — what a fractal is
❄️ See it happen: one rule, applied over and over
Start with a simple triangle. Then follow one instruction: take every straight edge, and change its middle third into a spike. Do the same to every new edge. That is the whole method — move the slider and watch a smooth triangle become a snowflake. After run 5 the new spikes are thinner than one pixel, so the view zooms in on one spike for you — and that small piece looks just like the whole snowflake. Every run after that zooms in deeper, all the way to run 11 — and the detail never runs out.
Show the Python code
# The Koch snowflake. The rule is four lines long and it calls itself.
from math import cos, sin, pi
import matplotlib.pyplot as plt
def kink(a, b):
"""Replace one edge a-b with the four edges that have a spike in the middle."""
dx, dy = (b[0] - a[0]) / 3, (b[1] - a[1]) / 3
p1 = (a[0] + dx, a[1] + dy) # one third along
p2 = (a[0] + 2*dx, a[1] + 2*dy) # two thirds along
t = -pi / 3 # turn the middle third 60° to make the tip
tip = (p1[0] + dx*cos(t) - dy*sin(t),
p1[1] + dx*sin(t) + dy*cos(t))
return [a, p1, tip, p2]
def koch(points, depth):
if depth == 0: # ← the base case
return points
out = []
for a, b in zip(points, points[1:]): # every edge, no exceptions
out += kink(a, b)
out.append(points[-1])
return koch(out, depth - 1) # ← and again, on its own output
# start with a triangle, close the loop, run the rule 5 times
tri = [(0, 0), (1, 0), (0.5, 3**0.5/2), (0, 0)]
pts = koch(tri, 5)
plt.plot(*zip(*pts)); plt.axis("equal"); plt.axis("off"); plt.show()
How it works. kink only knows how to
change one edge. koch uses it on every edge, then calls itself on the
result — so run 5 changes the edges that run 4 made. Each run multiplies the number of edges by
4 and divides their length by 3. That is why the outline gets longer every time,
while the snowflake stays the same size.
Why this is a fractal: every edge becomes 4 copies of itself at ⅓ size, so the
dimension is D = log 4 ⁄ log 3 ≈ 1.262 — not a whole number. The edge grows by
⁴⁄₃ every run, so its length goes to infinity — but the area inside stays finite. A
line of infinite length around a small piece of paper: no ordinary shape can do that.
代码怎么运作:
kink 只知道怎么修一条边,别的什么都不会。koch 把它用到每一条边上,然后在结果上调用它自己——所以第 5 轮替换的,是第 4 轮造出来的那些边。每跑一遍,边数乘以 4,边长除以 3,这就是为什么轮廓越来越长,而雪花的大小却不变。✅ 分形检验:每条边都被替换成它自己的 4 个 ⅓ 大小的副本,所以维数是
D = log 4 ⁄ log 3 ≈ 1.262——不是整数。而周长每跑一遍就乘以 ⁴⁄₃,于是它奔向无穷,可它围住的面积却是有限的。一条无限长的线,围住一小块有限的纸:这正是分形能做而普通形状做不到的事。โค้ดทำงานอย่างไร:
kink รู้แค่วิธีจัดการหนึ่งด้าน ไม่รู้อย่างอื่นเลย ส่วน koch เอามันไปใช้กับทุกด้าน แล้วเรียกตัวเองกับผลลัพธ์ — รอบที่ 5 จึงแทนที่ด้านที่รอบที่ 4 สร้างขึ้น แต่ละรอบจำนวนด้านคูณ 4 และความยาวหารด้วย 3 เส้นรอบรูปจึงยาวขึ้นทุกครั้งขณะที่เกล็ดหิมะยังขนาดเท่าเดิม✅ การทดสอบแฟร็กทัล: ทุกด้านถูกแทนด้วยสำเนาของตัวเอง 4 ชิ้นที่สเกล ⅓ มิติจึงเป็น
D = log 4 ⁄ log 3 ≈ 1.262 — ไม่ใช่จำนวนเต็ม และเส้นรอบรูปโตขึ้น ⁴⁄₃ ทุกรอบ มันจึงมุ่งสู่อนันต์ ขณะที่พื้นที่ที่มันล้อมไว้ยังจำกัด เส้นยาวไม่สิ้นสุดรอบกระดาษผืนเล็กๆ — นั่นคือสิ่งที่แฟร็กทัลทำได้ แต่รูปทรงธรรมดาทำไม่ได้✓ Check yourself — the Koch snowflake
🌿 In growth — fractals
A fractal (分形) is a shape that repeats at every size. Zoom in on one small part and you see the same pattern again — so the whole lives inside every part. A fern leaf is made of small leaves. A branch is a little tree. A bay on a coastline is full of smaller bays.
Here is the surprise: a fractal is not a long, difficult drawing. It is one short rule, used again and again. The rule for the tree below is only this:
“Draw a line. At its tip, start two smaller trees, each turned a little to the side. Stop when the tree gets too small.”
The last sentence is as important as the first. “Stop when…” is the base case — without it, the rule would run forever and nothing would ever appear. Every recursion needs a way to stop.
So a fractal has two faces: the rule is just four numbers on one line 🌍, but what you see is a whole living tree 🌏. The same thing — one side counts it; one side feels it.
Show the Python code
# ONE rule. Change the numbers above and watch these change too.
from math import cos, sin, radians
def branch(x, y, length, angle, depth):
if depth == 0: # ← the base case: STOP
return
draw_line(x, y, angle, length) # the trunk of this little tree
tip_x = x + cos(angle) * length
tip_y = y + sin(angle) * length
for i in range(2): # ← branches
turn = spread(i) * radians(28) # ← turn, in degrees
branch(tip_x, tip_y, length * 0.720, angle + turn, depth - 1)
# ↑ shrink ↑ one step closer to 0
# start it once — and the whole tree grows out of that one call:
branch(middle_x, bottom, trunk_len, UP, 9) # ← depth
Notice there is no code for “tree” anywhere — no
list of branches, no list of leaves. branch only knows how to draw one line and
then ask itself for two smaller trees. That is recursion (递归):
a rule that uses itself. The tree is what recursion looks like.
Why this is a fractal: branch calls itself, so every small branch is the whole tree again — turned by turn and made smaller by shrink. Press “show the small tree inside” and you can see that copy. This is exact self-similarity. (Only the depth slider makes it stop; the mathematical tree never stops.)
branch 调用它自己,所以每一根子枝都是整棵树的再现——按转角旋转、按收缩缩放。按下"显示里面的小树",你看到的就是那个副本本身。这是构造上就成立的严格自相似。(只有深度滑块让它变得有限;数学上的那棵树永不停止。)branch เรียกตัวเอง กิ่งย่อยทุกกิ่งจึงเป็นต้นไม้ทั้งต้นอีกครั้ง — หมุนด้วยมุม และย่อด้วยการหด กด "แสดงต้นไม้เล็กข้างใน" แล้วคุณกำลังมองสำเนานั้นตรงๆ นี่คือความคล้ายตัวเองแบบเป๊ะที่มาจากการสร้าง (มีแต่แถบความลึกที่ทำให้มันจำกัด ต้นไม้เชิงคณิตศาสตร์ไม่หยุดเลย)🎛️ What each number does — try to predict first
| Turn | How far each new branch turns away from its parent. Small = a tall thin plant; large = a wide open fan. Try 2°, then 72°. |
| Shrink | Must be less than 1, or the tree never stops growing. Near 0.5 the small branches disappear fast; near 0.85 the branches stay long and cross each other. 0.618 is 1 ÷ φ — the golden ratio from the key words. |
| Depth | How many times the rule can call itself. Every +1 doubles the number of branch tips — depth 3 is a small stick, but depth 12 is a forest. |
| Branches | How many new branches each tip makes. 2 = a tree; 5 = a firework. The number of lines grows very fast (branchesdepth), so the page must limit depth when you raise this — 5 branches at depth 6 is already 3,906 lines. |
Press “🔍 show the small tree inside”. One branch turns purple — and it is the same tree again, only smaller. That is self-similarity (自相似): the pattern of the whole is inside every part.
✓ Check yourself — the recursive tree
🔍 Zoom forever — the Mandelbrot set
The most famous fractal of all comes from a very short rule: z → z² + c, repeated. Some numbers stay small forever — they make the dark centre of the shape. Other numbers fly away to infinity. All the beauty is on the edge between the two. Now zoom in — as deep as you like.
Keep zooming. The same shape appears again and again, forever — that is self-similarity, and it never ends.
Show the Python code
# The Mandelbrot set. The maths is the middle three lines.
import numpy as np, matplotlib.pyplot as plt
def escape_time(c, max_iter=300):
z = 0
for n in range(max_iter):
z = z*z + c # ← the entire rule
if abs(z) > 2: # past 2 it can never come back
return n # how long it survived = its colour
return max_iter # never escaped -> inside the set
W, H = 640, 400
cx, cy, span = -0.65, 0.0, 3.1 # shrink span to zoom in
xs = np.linspace(cx - span/2, cx + span/2, W)
ys = np.linspace(cy - span*H/W/2, cy + span*H/W/2, H)
# every pixel is its own little experiment
img = [[escape_time(complex(a, b)) for a in xs] for b in ys]
plt.imshow(img, cmap="twilight_shifted"); plt.axis("off"); plt.show()
How it works. Python has complex numbers built in,
so z*z + c really is the whole rule — complex(a, b) turns a pixel’s
position into the number c. The abs(z) > 2 test is the exit door: when a point
gets further than 2 from the centre, it will always fly away, so the computer can stop. To zoom, make
span smaller and max_iter bigger — deep zooms need more patience.
Why this is a fractal: its edge is a line, so its dimension should be 1 — but in 1991 Shishikura proved the edge has dimension 2. A dimension bigger than expected is exactly Mandelbrot’s own definition of a fractal. It is also quasi-self-similar: keep zooming, and copies of the whole shape appear at every depth — a little changed, not exactly the same.
🔢 What z → z² + c actually does
z → z² + c
Read the arrow as “becomes”, not “equals”: the new z is the old z times itself, plus c. It is an instruction you repeat, not an equation you solve. Pick any point on the screen and call it c. Start at z = 0, and use the rule again and again. Only one question matters: do the numbers stay small, or do they run away?
- c = −1 → 0, −1, 0, −1… never runs away. Inside the set — painted black.
- c = 1 → 0, 1, 2, 5, 26, 677… gone. Outside — and the colour shows how fast it ran away.
That is the whole definition. Nobody drew the edge: the set is every point that passes the test, and the edge is simply where “stays” meets “runs away”. When |z| goes past 2, the point can never come back, so the computer can stop early. And because the points are complex numbers, squaring a number doubles its angle — that turning is where all the spirals in the picture come from.
The rule has two settings, and the one you hold still decides which picture you get:
| Mandelbrot | c = the pixel being tested · z starts at 0 | → the map |
| Julia | c = one fixed value · z starts at the pixel | → one world |
🤔 What Mandelbrot was after — and why it mattered
He was not looking for a pretty picture. Benoît Mandelbrot spent his whole career on one big complaint about mathematics. In 1982 he wrote:
“Clouds are not spheres, mountains are not cones, coastlines are not circles, and bark is not smooth, nor does lightning travel in a straight line.”
For three hundred years, geometry studied smooth, tidy things — lines, circles, spheres. These are perfect for planets, but they describe almost nothing you can see out of a window. In 1975 he gave the other kind of shape a name: fractal. It gave roughness a number. Today that number is used everywhere: scientists read it from broken metal, doctors see it change in sick lungs and heartbeats, and film studios use it to build every mountain and cloud you see on screen. It even helps explain why stock markets crash more often than people expect.
A short history. Julia and Fatou did the mathematics in 1917–20, with no computers — they never saw these shapes. Mandelbrot printed the first picture at IBM on 1 March 1980. The small dots around it looked like printer dirt — but they were tiny copies of the whole shape. Later, mathematicians proved its edge has dimension 2. One simple-sounding question about it, called MLC, still has no answer.
三百年来,几何学研究的都是光滑、整齐的东西——直线、圆、球——它们对炮弹和行星堪称完美,却几乎描述不了你从窗户看出去的任何东西。1975 年他为另一条路取名分形,而它给粗糙度一个数字。这个数字如今已是常规装备:材料科学家从断口上读出它,医生在病变的肺、视网膜和心跳中发现它改变了,电影里每一片可信的山和云都由它构建,它还解释了为什么市场崩盘远比钟形曲线预测的更频繁。
简短的来历:茹利亚与法图在 1917–20 年没有计算机、也从未见过这些图形的情况下完成了数学;1980 年 3 月 1 日曼德博在 IBM 打印出第一张图,周围的斑点被当成打印机脏了,其实是整个形状的微型副本;杜阿迪与哈伯德证明它是连通的,宍倉光広证明它的边界维数为 2。而一个听起来很简单的问题 MLC,至今仍未解决。
สามร้อยปีที่ผ่านมา เรขาคณิตศึกษาสิ่งที่เรียบและเป็นระเบียบ — เส้นตรง วงกลม ทรงกลม — ซึ่งสมบูรณ์แบบสำหรับลูกกระสุนและดาวเคราะห์ แต่แทบไม่ได้อธิบายอะไรเลยที่คุณเห็นนอกหน้าต่าง เขาตั้งชื่อทางเลือกนั้นว่า แฟร็กทัล ในปี 1975 และมันให้ตัวเลขแก่ความขรุขระ ตัวเลขนั้นกลายเป็นอุปกรณ์ธรรมดาไปแล้ว: นักวัสดุศาสตร์อ่านมันจากรอยแตก แพทย์พบว่ามันเปลี่ยนไปในปอด จอตา และจังหวะหัวใจที่ป่วย ทิวเขาและเมฆที่น่าเชื่อทุกภาพในหนังสร้างจากมัน และมันอธิบายว่าทำไมตลาดจึงล่มบ่อยกว่าที่เส้นโค้งระฆังทำนายไว้มาก
ประวัติโดยย่อ: ฌูเลียและฟาตูทำคณิตศาสตร์ไว้ใน 1917–20 โดยไม่มีคอมพิวเตอร์และไม่เคยเห็นรูปเหล่านี้ 1 มีนาคม 1980 มานเดลบรอตพิมพ์ภาพแรกที่ไอบีเอ็ม จุดรอบๆ ถูกเข้าใจว่าเครื่องพิมพ์สกปรก แต่กลับเป็นสำเนาจิ๋วของรูปทั้งรูป ดูอาดีและฮับบาร์ดพิสูจน์ว่ามันเชื่อมต่อกัน ชิชิกูระพิสูจน์ว่าขอบมีมิติเท่ากับ 2 และคำถาม MLC ยังไม่มีคำตอบ
🗺️ Go and look — pick a point, see its world
The left picture is the map: the Mandelbrot set. Drag the cross anywhere and the right picture changes — it shows the Julia set that belongs to the point you are touching. Every point on the map is a door to a different fractal.
The map · pick a c
That point’s world · its Julia set
Stay inside the black part of the map, and the world on the right is one connected piece. Move outside, and it breaks into dust — the change happens the moment you cross the edge. (On the edge itself, no test can tell you which one it is.)
Show the Python code
# Mandelbrot and Julia are the SAME loop. Only the roles of z and c swap.
def escape(z, c, max_iter=300):
for n in range(max_iter):
z = z*z + c
if abs(z) > 2:
return n
return max_iter
# THE MAP: c changes with the pixel, z always starts at 0
mandelbrot = [[escape(0, complex(a, b)) for a in xs] for b in ys]
# ONE WORLD: c is fixed, z starts at the pixel
c = complex(-0.123, 0.745) # the "rabbit"
julia = [[escape(complex(a, b), c) for a in xs] for b in ys]
# and the map tells you what the world will look like before you draw it:
if escape(0, c) == 300:
print("c is inside M -> this Julia set is ONE connected piece")
else:
print("c is outside M -> this Julia set is dust")
How it works. Look at the two picture lines — they call the same function. For the map, c is the pixel you are on and z starts at 0. For a world, c stays fixed and z starts at the pixel. That one swap is the whole relationship: the Mandelbrot set asks one yes-or-no question about every possible Julia set. It is an index — one dot for each world.
Why Julia sets are fractals too: the rule z → z² + c maps the set exactly onto
itself. Every small piece, stretched by the rule, becomes the whole set again — the self-similarity
is part of the definition. Most Julia sets have a dimension that is not a whole
number.
只要停留在地图黑色主体的内部,右边的世界就是连成一片的;一旦走到外面,它就碎成尘埃——而且你一离开边界,这个转变立刻发生。
代码怎么运作:看那两行列表推导式——它们调用的是同一个函数。对地图来说,c 是你所在的像素,而 z 从 0 开始;对一个世界来说,c 被固定住,而 z 从像素开始。这一次交换就是二者的全部关系:曼德博集合,就是对每一个可能的 c,问一个关于它的茹利亚集的是非题,然后把答案画出来。它是一份索引——一个世界一个点。
✅ 分形检验:规则
z → z² + c 把茹利亚集精确地映射回它自己,所以任意小的一块,经过迭代拉伸后都会重新变成整个集合——这种自相似是写进定义里的,而不是观察出来的。它们大多具有非整数维数;当 c 很小时甚至有公式:D ≈ 1 + |c|²⁄(4 log 2)。อยู่ในเนื้อสีดำของแผนที่ โลกทางขวาจะเป็นชิ้นเดียวเชื่อมต่อกัน ก้าวออกไปข้างนอกเมื่อไร มันแตกเป็นผงธุลี — และการข้ามเส้นนั้นเกิดขึ้นทันทีที่คุณออกจากขอบ
โค้ดทำงานอย่างไร: ดูลิสต์คอมพรีเฮนชันสองบรรทัด — มันเรียกฟังก์ชันเดียวกัน สำหรับแผนที่ c คือพิกเซลที่คุณอยู่ และ z เริ่มที่ 0 สำหรับหนึ่งโลก c ถูกตรึงไว้ และ z เริ่มที่พิกเซล การสลับเพียงครั้งเดียวนั้นคือความสัมพันธ์ทั้งหมด: เซตมานเดลบรอตคือภาพที่ได้จากการถามคำถามใช่/ไม่ใช่ข้อเดียวเกี่ยวกับเซตฌูเลียของมัน สำหรับทุกค่า c ที่เป็นไปได้ มันคือสารบัญ — หนึ่งจุดต่อหนึ่งโลก
✅ การทดสอบแฟร็กทัล: กฎ
z → z² + c แมปเซตฌูเลียลงบนตัวมันเองพอดี ชิ้นเล็กเท่าใดก็ตามเมื่อถูกยืดด้วยการวนซ้ำจะกลายเป็นเซตทั้งหมดอีกครั้ง — ความคล้ายตัวเองที่ฝังอยู่ในนิยาม ไม่ใช่แค่สังเกตเห็น ส่วนใหญ่มีมิติไม่เป็นจำนวนเต็ม และเมื่อ c เล็ก มีสูตรด้วยซ้ำ: D ≈ 1 + |c|²⁄(4 log 2)🔢 这条规则在做什么:把箭头读作"变成"而不是"等于"——新的 z 等于旧的 z 平方再加上 c。在屏幕上任取一点叫它 c,从 z = 0 开始反复套用。c = −1 得到 0, −1, 0, −1……永远不逃,在集合里面(黑色);c = 1 得到 0, 1, 2, 5, 26, 677……逃走了,外面的颜色只是一只秒表。一旦 |z| 超过 2 就再也回不来,所以计算机可以提前停手;但"还在"永远不是证明,只是耐心用完了——这就是放得越深、每个像素越贵的原因。这些点是复数,而复数平方会把幅角加倍——图中所有的螺旋都来自那个旋转。
这条规则有两个旋钮:曼德博集合=c 是被测试的像素、z 从 0 开始("地图");茹利亚集=c 固定、z 从像素开始("一个世界")。
🔢 กฎนี้ทำอะไร: อ่านลูกศรว่า "กลายเป็น" ไม่ใช่ "เท่ากับ" — z ตัวใหม่คือ z ตัวเก่ายกกำลังสอง บวก c เลือกจุดใดก็ได้บนจอ เรียกว่า c เริ่มที่ z = 0 แล้วทำซ้ำ c = −1 ได้ 0, −1, 0, −1… ไม่มีวันหนี จึงอยู่ข้างใน (สีดำ) ส่วน c = 1 ได้ 0, 1, 2, 5, 26, 677… หนีไปแล้ว สีข้างนอกคือนาฬิกาจับเวลา เมื่อ |z| เกิน 2 แล้วกลับมาไม่ได้อีก คอมพิวเตอร์จึงหยุดก่อนได้ แต่ "ยังอยู่" ไม่เคยเป็นข้อพิสูจน์ เป็นเพียงความอดทนที่หมดลง — เพราะอย่างนี้การซูมลึกจึงแพงขึ้นต่อพิกเซล จุดเหล่านี้เป็นจำนวนเชิงซ้อน การยกกำลังสองจะเพิ่มมุมเป็นสองเท่า — เกลียวทั้งหมดมาจากการหมุนนั้น
กฎนี้มีสองปุ่ม: มานเดลบรอต = c คือพิกเซลที่ถูกทดสอบ, z เริ่มที่ 0 ("แผนที่"); ฌูเลีย = c ถูกตรึง, z เริ่มที่พิกเซล ("หนึ่งโลก")
✓ Check yourself — the Mandelbrot set
🎲 The chaos game — order out of pure luck
Press start and the computer plays a dice game 70,000 times. You do not need to do anything — just watch where the dots land. The three orange corners never move. One moving point jumps between them, following one rule, forever.
Random dots, one simple rule — and the Sierpiński triangle builds itself.
Show the Python code
# The chaos game. Six lines, and no triangle is ever described.
import random, matplotlib.pyplot as plt
corners = [(0, 0), (1, 0), (0.5, 3**0.5/2)]
p = (0.31, 0.17) # anywhere at all; it does not matter
xs, ys = [], []
for i in range(70_000):
c = random.choice(corners) # roll a three-sided die
p = ((p[0] + c[0]) / 2, # move HALF WAY to it
(p[1] + c[1]) / 2)
if i > 12: # let the point fall onto the shape first
xs.append(p[0]); ys.append(p[1])
plt.scatter(xs, ys, s=0.1, color="teal")
plt.axis("equal"); plt.axis("off"); plt.show()
How it works. random.choice only
decides which corner comes next. The halving does the real work: every jump pulls the point
closer to the shape, so after about twelve rolls the point is stuck on the Sierpiński triangle, no
matter where it started — that is what if i > 12 is for. Change corners
to the four corners of a square and you get a solid square instead, because four half-size squares
fill the big square with no hole.
Why this is a fractal: the Sierpiński triangle is made of exactly three copies of itself, each at half size. So you can find the dimension in one line: 3 copies at size ½, so D = log 3 ⁄ log 2 ≈ 1.585. More than a line, less than an area — and never a whole number, however far you zoom.
D = log 3 ⁄ log 2 ≈ 1.585。比线多,比面少,而且无论放大多少倍,永远不是整数。D = log 3 ⁄ log 2 ≈ 1.585 มากกว่าเส้น น้อยกว่าพื้นที่ และไม่มีวันเป็นจำนวนเต็ม🎯 The rule the computer is following
It is three lines long, and it never changes:
- Keep one moving point. It can start anywhere — a corner, the middle, off to one side. It really does not matter, and that is part of the surprise.
- Roll a dice to choose one of the corners: A, B or C. Every corner has the same chance, every time. The dice has no memory.
- Move the point half-way to the corner you rolled:
point = (point + corner) / 2. Draw a dot there. Then go back to step 2.
That is the whole program. It never talks about a triangle, and the dots land in a different order every time you run it. Yet the same picture appears every time.
🕳️ The dots never draw a triangle — they draw the holes
This part is the opposite of what it looks like. Nothing here draws triangles. The dots simply land where they are allowed to land — and the triangles you see are the places where they are not allowed to land. The pattern is made of empty spaces.
One jump closes the middle. The step is p → (p + corner) / 2. Now imagine
moving the whole triangle half-way towards corner A. You get a perfect copy of it at
half size, sitting in corner A. The same is true for B and C. So every jump must land the dot
inside one of three half-size triangles — and the upside-down triangle in the middle is not
part of any of them. After one jump, the dot is always inside one of the copies. It cannot land
in the middle. That is the big hole, and it appears after a single step.
Try to break it. Start the dot at (0.5, 0.30) — right inside the middle hole. Roll A and it jumps to (0.25, 0.15), already inside A’s copy. It leaves the hole on the first jump, and it can never go back in.
And that is why holes appear at every size. Call the place the dots can reach S. One line describes it: S is three copies of S, each at half size, one in each corner. If S has a hole in the middle, then each half-size copy of S has the same hole, at half size — and each of those is three copies again. Holes inside holes inside holes, without end. What is left is the Sierpiński triangle — the only shape these three rules do not change.
Mathematicians call this shape an attractor. The name is a good one: wherever the dot
starts, every jump cuts its distance to the shape in half. After about twelve jumps it is closer
than one pixel, and it can never leave. That is why the code says if i > 12 — the
first few dots are still falling in, and drawing them would leave marks in the wrong places.
So what does the randomness really do? It only chooses which copy the dot visits next — never whether the dot is on the shape. Over time, the dice sends the dot to every part of the shape, so the picture fills in evenly. The randomness is the painter; the rule decides where paint is allowed. That is also why you need so many dots: with 200 you see only a mess, and the shape only becomes clear after tens of thousands.
The final test. Run the same rule with the four corners of a square, and you get a solid square — no fractal at all. Four half-size squares fill the big square exactly, with no gap, so nothing is cut out. The hole is not decoration: it is the whole reason there is a fractal here.
🎯 计算机在遵守的规则(只有三行,而且从不改变):1) 保留一个移动的点。它可以从任何地方开始——角上、中间、旁边都行,真的无所谓,这正是惊喜的一部分。2) 掷一个三面骰,选出 A、B、C 中的一个角。每个角的概率相同,每一次都如此;骰子没有记忆。3) 把这个点移动到它现在的位置与所选角之间的正中点:
point = (point + corner) / 2,在那里画一个点,然后回到第 2 步。整个程序就这些。里面没有任何地方描述过三角形,而且点被画出来的顺序完全无法预测——跑两次,没有任何两个点会按同样的顺序落下。然而每一次出现的都是同一幅图。
🕳️ 这些点从来没有在画三角形——它们画的是"洞":这一点值得弄清楚,因为它和看上去的正好相反。这里没有任何东西在画三角形。点只是堆积在它们被允许落下的地方,而你看见的那些三角形,恰恰是它们被禁止落下的地方。这个图案是由"缺席"构成的。
一次跳跃就排除了中间。这一步是
p → (p + 角) / 2。把"朝 A 角走一半"不是用在一个点上,而是用在整个三角形上,你会得到它一半大小的完整副本,塞在 A 角里;B、C 同理。所以这三个动作合起来,只可能把点落进三个半尺寸三角形之一——而中间那个倒立的三角形不属于其中任何一个。无论这个点之前在哪里,它一跳就落进了某个副本里。它落不到中间。这就是那个大洞,一步之后就存在了。试着破坏它。让点从 (0.5, 0.30) 出发——正好在被禁止的中间。掷到 A,它跳到 (0.25, 0.15),已经在 A 的副本里了。它在第一跳就出了洞,而且再也回不去。
这就是为什么每个尺度上都有洞。把点能到达的区域叫作 S。一句话就能描述它:S 由 S 的三个副本组成,每个都是一半大小,一角一个。所以如果 S 中间有一个洞,那么 S 的每一个半尺寸副本中间也有同样的洞,只是小一半——而那些副本又各自由三个副本组成。洞里有洞,洞里还有洞,没有尽头。剩下的就是谢尔宾斯基三角形,也是这三条规则唯一不会改动的形状。
数学家把这样的剩余物叫作吸引子(attractor),把这三条收缩规则叫作迭代函数系统(IFS)。"吸引子"这个词很准确:无论点从哪里出发,每跳一次它到这个形状的距离就减半,所以十几跳之内它就比一个像素还近,而且再也离不开。代码里
if i > 12 就是为此而写——最前面那些点还在"掉进来",画出来只会留下明显的杂点。那么随机到底在做什么?它决定这个点接下来去哪一个副本,而从不决定这个点是否在形状上。一串掷出的结果,比如 B、C、A……就是一个地址:"在 B 的副本里,在它的 C 子副本里,在那个的 A 子子副本里。"只要投掷次数够多,一枚公平的骰子会走遍每一个深度上的每一个地址,于是允许的区域被均匀填满,而不是挤成一团。随机是画笔,规则是模板。这也是为什么需要这么多点:200 个点你只看到散乱,要几万个点,形状才会显现出来。它是统计地浮现的。
决定性的检验。用正方形的四个角跑同一条规则,你会得到一个实心正方形——完全没有分形。四个半尺寸正方形正好铺满它们的父图形,不留任何空隙,所以什么也没有被挖掉。那个洞不是装饰:它正是这里之所以有分形的全部原因。
🎯 กฎที่คอมพิวเตอร์ทำตาม (สามบรรทัด ไม่เคยเปลี่ยน): 1) เก็บจุดเคลื่อนที่ไว้หนึ่งจุด มันเริ่มที่ไหนก็ได้ — ที่มุม ตรงกลาง หรือด้านข้าง ไม่สำคัญเลยจริงๆ และนั่นคือส่วนหนึ่งของความน่าประหลาดใจ 2) ทอยลูกเต๋าสามหน้า เพื่อเลือกมุม A, B หรือ C ทุกมุมมีโอกาสเท่ากันทุกครั้ง ลูกเต๋าไม่มีความทรงจำ 3) ย้ายจุดไปยังจุดกึ่งกลางพอดีระหว่างตำแหน่งปัจจุบันกับมุมที่ทอยได้:
point = (point + corner) / 2 วาดจุดตรงนั้น แล้วกลับไปข้อ 2โปรแกรมทั้งหมดมีแค่นี้ ไม่มีที่ใดในนั้นอธิบายรูปสามเหลี่ยมเลย และลำดับการวาดจุดก็เดาไม่ได้เลย — รันสองครั้ง ไม่มีจุดคู่ไหนตกตามลำดับเดียวกัน แต่ภาพที่ได้เหมือนกันทุกครั้ง
🕳️ จุดเหล่านี้ไม่เคยวาดสามเหลี่ยม — มันวาด "รู": ตรงนี้ควรทำความเข้าใจให้ชัด เพราะมันตรงข้ามกับที่ตาเห็น ไม่มีอะไรที่นี่กำลังวาดสามเหลี่ยม จุดแค่กองรวมกันตรงที่มันได้รับอนุญาตให้ตก และสามเหลี่ยมที่คุณเห็นคือที่ที่มันถูกห้ามไม่ให้ตก ลวดลายนี้สร้างจากการ "ไม่มี"
กระโดดครั้งเดียวก็ตัดตรงกลางออก ขั้นตอนคือ
p → (p + มุม) / 2 ลองใช้ "ไปครึ่งทางหามุม A" ไม่ใช่กับจุดเดียว แต่กับสามเหลี่ยมทั้งรูป คุณจะได้สำเนาที่สมบูรณ์ของมันในขนาดครึ่งหนึ่ง ซุกอยู่ที่มุม A เช่นเดียวกับ B และ C ดังนั้นสามการเคลื่อนที่รวมกันจะพาจุดไปตกได้เพียงในหนึ่งในสามเหลี่ยมครึ่งขนาดสามรูป — และสามเหลี่ยมกลับหัวตรงกลางไม่ได้เป็นของรูปใดในสามรูปนั้น ไม่ว่าจุดจะอยู่ที่ไหนมาก่อน ทันทีที่มันกระโดด มันจะอยู่ในสำเนาใดสำเนาหนึ่ง มันตกตรงกลางไม่ได้ นั่นคือรูใหญ่ และมันมีอยู่ตั้งแต่ก้าวเดียวลองทำลายมันดู เริ่มจุดที่ (0.5, 0.30) — ตรงกลางที่ต้องห้ามพอดี ทอยได้ A มันกระโดดไปที่ (0.25, 0.15) ซึ่งอยู่ในสำเนาของ A แล้ว มันออกจากรูตั้งแต่กระโดดครั้งแรก และไม่มีอะไรพากลับเข้าไปได้อีก
และนั่นคือเหตุผลที่มีรูในทุกขนาด เรียกบริเวณที่จุดไปถึงได้ว่า S อธิบายได้ในบรรทัดเดียว: S คือสำเนาของ S สามชิ้น แต่ละชิ้นครึ่งขนาด มุมละหนึ่ง ถ้า S มีรูตรงกลาง สำเนาครึ่งขนาดของ S แต่ละชิ้นก็มีรูเดียวกันในขนาดครึ่งหนึ่ง และแต่ละชิ้นนั้นก็ประกอบด้วยสำเนาสามชิ้นอีก รูในรูในรู ไม่มีที่สิ้นสุด สิ่งที่เหลือคือสามเหลี่ยมเซียร์พินสกี และเป็นรูปทรงเดียวที่กฎทั้งสามไม่แตะต้อง
นักคณิตศาสตร์เรียกสิ่งที่เหลือแบบนี้ว่า ตัวดึงดูด (attractor) และเรียกกฎหดสามข้อว่า ระบบฟังก์ชันวนซ้ำ (IFS) คำว่า "ตัวดึงดูด" ตรงเป๊ะ: ไม่ว่าจุดเริ่มที่ไหน ทุกกระโดดจะลดระยะห่างจากรูปทรงลงครึ่งหนึ่ง ภายในสิบกว่ากระโดดมันจึงใกล้กว่าหนึ่งพิกเซลและออกไปไม่ได้อีก นั่นคือหน้าที่ของบรรทัด
if i > 12 — จุดแรกๆ เหล่านั้นยังกำลังตกเข้ามา ถ้าวาดออกมาจะเหลือจุดหลงเห็นได้ชัดแล้วความสุ่มทำอะไรกันแน่? มันเลือกว่าจุดจะไปเยือนสำเนาอันไหนต่อไป — ไม่เคยเลือกว่าจุดนั้นอยู่บนรูปทรงหรือไม่ ลำดับการทอยอย่าง B, C, A… คือที่อยู่: "ในสำเนาของ B ในสำเนาย่อย C ของมัน ในสำเนาย่อยย่อย A ของอันนั้น" ลูกเต๋าที่ยุติธรรมจะไปเยือนทุกที่อยู่ในทุกระดับ บริเวณที่อนุญาตจึงเต็มอย่างสม่ำเสมอแทนที่จะกระจุก ความสุ่มคือพู่กัน กฎคือแม่แบบ และนั่นคือเหตุผลที่ต้องใช้จุดมากขนาดนี้: 200 จุดคุณเห็นแค่ความกระจัดกระจาย รูปทรงจะชัดก็ต่อเมื่อผ่านไปหลายหมื่นจุด มันปรากฏขึ้นมาเชิงสถิติ
การทดสอบชี้ขาด ลองใช้กฎเดียวกันกับสี่มุมของสี่เหลี่ยมจัตุรัส แล้วคุณจะได้สี่เหลี่ยมทึบ — ไม่มีแฟร็กทัลเลย สี่เหลี่ยมครึ่งขนาดสี่รูปปูเต็มรูปแม่พอดี ไม่เหลือช่องว่าง จึงไม่มีอะไรถูกเจาะออก รูไม่ใช่ของตกแต่ง: มันคือเหตุผลทั้งหมดที่ทำให้ตรงนี้มีแฟร็กทัล
✓ Check yourself — the chaos game
🔵 One that is not a fractal — Buckminster Fuller’s dome
Richard Buckminster Fuller — “Bucky” — patented the geodesic dome in 1954. All his life, he argued that nature builds with as few parts as possible. His domes became radar stations in the Arctic and the Montreal Biosphere at Expo 67. When chemists later found a carbon molecule shaped like a football, they named it buckminsterfullerene after him.
A dome is built the same way as the fractals on this page — by one rule, repeated: take a triangle, cut it into smaller triangles, and push the new corners out onto the ball. Do it again to every new triangle. That is iteration — the same move as the snowflake. So is it a fractal? Try it and watch what the repeating does.
🔵 Subdivide a dome — and watch it get smoother
Start with 20 triangles (an icosahedron). Each pass cuts every triangle into smaller ones and pushes the corners out to the ball. Move the frequency slider and watch the gap number — it shows how far the surface still is from a perfect ball.
Show the Python code
# Geodesic subdivision, and the measurement that settles the question.
from math import sqrt, dist
def unit(p): # push a point out onto the sphere
n = sqrt(sum(c*c for c in p))
return tuple(c/n for c in p)
def subdivide(faces, freq):
out = []
for A, B, C in faces: # cut each triangle freq x freq
for i in range(freq):
for j in range(freq - i):
P = lambda u, v: unit(tuple(
(A[k]*(freq-u-v) + B[k]*u + C[k]*v) / freq for k in range(3)))
out.append((P(i, j), P(i+1, j), P(i, j+1)))
if j < freq - i - 1:
out.append((P(i+1, j), P(i+1, j+1), P(i, j+1)))
return out
# How far does the flat surface still miss the true sphere?
for freq in (1, 2, 4, 8, 16):
tris = subdivide(icosahedron, freq)
gap = max(1 - sqrt(sum(((a[k]+b[k]+c[k])/3)**2 for k in range(3)))
for a, b, c in tris)
print(freq, len(tris), f"{gap:.4%}")
# 1 20 20.5346% <- and it keeps HALVING
# 2 80 6.5828%
# 4 320 1.7753%
# 8 1280 0.4528%
# 16 5120 0.1138% <- heading to zero: a smooth ball
How it works. The loop has the same shape as the Koch code — one rule used on its own output. The difference is the last line, and it is the whole answer: measure the gap, and it halves every time. The snowflake’s edge multiplied by 4⁄3 every time. One number runs to zero; the other runs to infinity.
A geodesic dome is not a fractal. Zoom into the snowflake and you find more spikes, forever. Zoom into a dome and you find a flat triangle — and then nothing. The detail runs out. The surface gets closer and closer to a perfectly smooth ball, and a ball’s surface has dimension exactly 2 — a whole number. Fuller did not want roughness; he wanted the opposite — the strongest, simplest copy of a smooth ball, made from the fewest straight bars.
🔺 What Fuller really wanted — and why the answer had to be the triangle
His thinking started from something very simple: two points cannot make a shape. Two points only give you a line — a length, nothing more. There is no inside and no area. Three points is the smallest number that can close a space. So the triangle is not just a good shape; it is the first shape that exists.
Then a second fact does the real work. The triangle is the only straight-sided shape that cannot be pushed out of shape. Make a square from four sticks with loose corners and push it — it leans over into a diamond, and no stick changed its length. Push a triangle and nothing happens: to move it, you would have to make a side longer or shorter. A triangle is strong because of its shape, not because of strong corners. Every other shape needs extra support — and the support you add is always a triangle.
Fuller took the same idea one step up: if three points are the smallest number to close a flat space, then four points are the smallest number to close a 3-D space — the tetrahedron. From there, the dome follows naturally. A ball holds the most space with the least surface. Triangles are the only panels that hold their shape without help. So: build a ball shape completely out of triangles, and you get the most space, with the least material, and no extra supports anywhere. He argued that a dome even gets stronger, compared to its weight, as you build it bigger.
And that is exactly why it is not a fractal. Look at what Fuller wanted: fewer parts. Every extra cut was a cost he paid only to get closer to smooth. A fractal wants the opposite — it wants the detail to keep coming, forever, at every size. Two designs, the same triangle-cutting loop, opposite goals: one repeats to make roughness disappear; the other repeats to make sure it never disappears.
🧠 Why this section is here at all
Everything else on this page is an example. This one is a non-example — and it teaches more than any of the others. Here is why.
1. You only understand a word when you can say what it does not include. Anyone can agree that “a fractal repeats at every size”. The real test is to see something that looks like a fractal, and explain why it is not one. If every shape you see is a fractal, you never have to think — you just agree.
2. It kills the most common wrong idea about fractals. Many people believe “made by repeating a rule = fractal”. The dome shows this is wrong, because it is built by exactly that kind of loop — take a triangle, cut it, repeat. Same method as the snowflake, opposite result.
3. It turns the definition into a test you can run. “It looks complicated” is only a feeling. “Does the detail stay at every size, or does it run out?” is a question with an answer — and on this page the answer is a number. The snowflake’s edge grows by 4⁄3 each pass and runs to infinity. The dome’s gap halves each pass and runs to zero. You do not have to argue; you can watch the numbers.
4. The same difference matters in real work. Computer graphics programs repeat a rule until the detail disappears — they cut a surface into pieces smaller than a pixel, and then the model is finished. A fractal repeats until the detail never disappears. Same loop, opposite goal, different tools.
5. It keeps the page honest. People tell many false stories about this subject — and geodesic domes are often called “fractal architecture”. The habit that protects you is always the same: ask what the number does as you zoom in. Fuller deserves respect too. He was not trying to make infinite roughness and failing; he was solving the opposite problem — and he solved it beautifully.
One sentence to remember: a fractal is not about how it is made, but about what is still there when you look closer. If the detail runs out, you have a dome. If the detail keeps coming, you have a fractal.
⚙️ Why this is useful: patterns save work, and a target helps you improve
This way of thinking is useful even if you never draw a snowflake again. It gives you two things that are hard to get any other way.
1. A pattern replaces a list — and that saves a lot of work. Look at what this page really stores. The tree at depth 12 draws 4,095 lines, but its whole description is four numbers and one short rule. The Koch snowflake reaches 3,072 edges from about ten lines of Python. A seed cannot hold a map of every leaf, but it can hold a rule. When you see that a big thing is made of smaller copies of itself, you stop writing the parts and start writing the rule — and thousands of items become one.
This is not just a picture of programming — it is programming. Seeing that a problem holds smaller copies of itself turns a slow answer into a fast one: sorting a million records by cutting the list in half, again and again, is about a million times less work than comparing every pair. Games grow whole worlds from one seed number. The idea is always the same — find the self-similar structure and write the rule, not the list.
2. A clear target lets you improve step by step. The dome shows this quietly. The dashed circle is the target, and the gap number tells you how far away you still are: 20.5%, then 6.6%, then 1.8%, then 0.45%. You do not have to argue about whether the shape is “better” — you can measure it, and stop when the next pass is not worth the extra 960 triangles. That is the whole engineering loop: make one change, measure it, keep it or throw it away, repeat.
Notice how much of this page works that way. Not “the snowflake gets rougher”, but ×4⁄3 every pass. Not “the Mandelbrot edge is complicated”, but dimension 2. Not “the dome looks smooth enough”, but 0.45%. Each one turns an opinion into something you can check — and when you can check a thing, you can improve it on purpose, not by luck. The pattern gives you the small rule; the target tells you if repeating it is taking you anywhere.
而穹顶的建造方式,和本页那些分形完全一样——一条规则,不断重复:取一个三角形,切成更小的三角形,再把新的角点推到球面上。然后对每个新三角形再来一次。这就是迭代,和雪花是同一个动作。那么它是分形吗?试试看,注意这种重复带来了什么。
🔵 细分一个穹顶——然后看着它变得更"光滑":从二十面体开始:20 个三角形。每一轮都把每个三角形切得更小,并把角点推到球面上。拖动频率,看那个gap(间隙)读数——它表示这个表面距离一个完美的球还差多远。
❌ 分形检验——这一个没通过:测地线穹顶不是分形。放大雪花,你会找到更多的尖角,永远如此;放大穹顶,你找到的是一个平的三角形,然后就没有了——细节用完了。它的表面收敛到一个完美光滑的球面,维数正好是 2,一个整数。富勒追求的不是粗糙,恰恰相反——他要用最少的直杆,做出对光滑球体最坚固、最高效的逼近。
🧠 这一节为什么会在这里:本页其他内容都是例子,只有这一节是反例,而它做的工作比任何一个例子都多。理由如下。
1. 你只有说得出一个词排除了什么,才算真正懂了它。"分形在每个尺度上重复",谁都能点头同意。真正的检验,是把一个看起来该算的东西递到你面前,而你能准确说出它为什么不算。如果给你看的每个形状都是分形,你就永远不必思考,只需附和。
2. 它击碎了关于分形最常见的错误观念。几乎每个半懂不懂的人都会带走这样一个印象:"由重复的规则造出=分形"。穹顶是最干净的反驳,因为它正是用那种循环造出来的——取一个三角形,切开,重复。和雪花是同一套机制,结果却相反。一个用完全不同方式造出来的反例什么也证明不了;而这一个共享了方法,却依然不合格。
3. 它把定义变成一个你真能执行的检验。"看起来很复杂""有重复的部分"都只是印象。而细节在每个尺度上是存活还是消失?是一个有答案的问题——在本页上它还是一个数字。雪花的周长每轮乘以 4⁄3,奔向无穷;穹顶的间隙每轮减半,趋于零。你不必争辩,看读数就行。
4. 这正是真实工作中要紧的那个区分。把一条规则迭代到细节消失,正是数值方法和图形引擎每天在做的事——把一个曲面细分到面片小于一个像素,模型就完成了。而迭代到细节持续存在,那就是分形。同一个循环,相反的极限,完全不同的工具。分清自己手里是哪一个,是个实用问题,不是哲学问题。
5. 它让这一页保持诚实。这个题材吸引的神话比几乎任何数学分支都多——帕特农神庙里的黄金比例、鹦鹉螺里的 φ,以及没错,测地线穹顶也经常被说成"分形建筑"。每一次能保护你的习惯都是同一个:问一问,当你放大时那个数字在做什么。富勒也值得这份尊重。他不是想追求无限的粗糙却失手了;他解决的是相反的问题——用最少的直杆做出对光滑球体最坚固的逼近——而且解得很漂亮。
🔺 富勒真正在优化什么——以及他怎么知道答案必然是三角形:他的推理从一件几乎不值一提的事开始:两个点做不出一个形状。两个点只给你一条线——一段长度,别无其他;没有内部,没有面积,没有"东西"。三个点才是能围住任何东西的最小数目,所以三角形不只是一个好形状,它是第一个能存在的形状。
接着,第二个事实完成了真正的工作:三角形是唯一一种推不变形的多边形。拿四根杆、角上用活动销做成一个正方形,往侧面一压——它就歪成菱形,而没有任何一根杆改变长度。对三角形做同样的事,什么也不会发生:要让它动,你必须真的把某条边变长或变短。三角形的刚性来自它的几何,而不是来自僵硬的接头。其他每一种多边形都需要加撑——而你加上去的那根撑,永远构成一个三角形。
富勒把同样的论证往上推了一维:如果三个点是围出面积的最小数目,那么四个点就是围出体积的最小数目——四面体;他称之为宇宙中的最小系统,并把它作为整个协同几何学(synergetics)的基石。从这里,穹顶几乎是必然的结论:球是所有形状中以最小表面积容纳最大体积的那一个;三角形是唯一不需要帮助就能保持形状的面板。于是——完全用三角形去逼近一个球,你就得到最大的容纳空间、最少的材料,而且任何地方都不需要加撑,每根杆件都处于纯粹的拉伸或压缩状态。他主张这是唯一一种越造得大、强度相对自重反而越高的结构。
而这恰恰就是它不是分形的原因。看看他在最小化什么:零件数。富勒要的是用尽可能少的杆件完成任务,每一次多细分都是他为了更接近光滑而付出的代价。分形想要的正相反——它要细节源源不断,永远,在每一个尺度上。两种设计,同一个"切三角形"的循环,目标却相反:一个在花费迭代让粗糙消失,另一个在花费迭代确保粗糙永不消失。
值得记住的一句话:分形不是由它怎么造出来定义的,而是由你凑近看时还剩下什么定义的。重复一条规则而细节消失了,你得到的是穹顶;重复一条规则而细节源源不断,你得到的才是分形。
⚙️ 实用的回报:模式思维带来效率,也带来可以用来改进的标尺。即使你以后再也不画雪花,这种思考方式仍然值得学,因为它给你两样别处很难得到的东西。
1. 用一个模式取代一份清单——这就是纯粹的效率。看看本页真正存下来的是什么:深度 12 的那棵树画了 4,095 条线,而它的全部描述只是四个数字加一句你能念出来的规则;科赫雪花从大约十行 Python 长到 3,072 条边。一颗种子装不下每一片叶子的地图,却能轻松装下一条规则。当你发现一个大东西是由自己的更小副本构成时,你就不再罗列部件,而是去写那条规则——于是你需要存储、传输、记忆或调试的东西,从成千上万项塌缩成一项。
这不是编程的比喻,这就是编程。发现一个问题内部包含它自己的更小版本,正是把慢解法变成快解法的关键:把一百万条记录不断对半拆开来排序,工作量大约是两两比较的百万分之一。游戏用一个种子数生成整片地貌,而不是把地貌打包进安装文件;图形引擎把曲面细分到细节小于一个像素就停下。每一次都是同一个洞见——找到自相似的结构,写规则,而不是写清单。
2. 有一个具体的比较对象,你才能一步步改进复杂的过程。这正是穹顶悄悄示范的东西。那圈虚线是目标,而 gap 读数是一个告诉你还差多远的数字:20.5%、6.6%、1.8%、0.45%。你不必争论这个形状是不是"更好"了——你可以量出来,判断下一轮是否值得多花 960 个三角形,并在不值得时停手。这就是完整的工程循环:做一次改动,对照固定参照测量,保留或放弃,再来一次。
留意本页有多少内容是这样搭起来的。不是"这片雪花变粗糙了",而是每一轮轮廓乘以 4⁄3;不是"曼德博的边界很复杂",而是维数 2;不是"这个穹顶看起来够光滑了",而是0.45%。每一个都把一件见仁见智的事,变成一件可以核查的事——而一旦可以核查,改进就可以是有意为之,而不是靠运气。模式思维给你那条小小的规则;具体的标尺告诉你,重复它到底有没有带你往前走。
และโดมถูกสร้างด้วยวิธีเดียวกับแฟร็กทัลในหน้านี้เป๊ะ — กฎเดียว ทำซ้ำ: เอาสามเหลี่ยมมาตัดเป็นสามเหลี่ยมเล็กลง แล้วดันมุมใหม่ออกไปที่ผิวทรงกลม แล้วทำซ้ำกับทุกสามเหลี่ยมใหม่ นั่นคือการวนซ้ำ เหมือนเกล็ดหิมะทุกประการ แล้วมันเป็นแฟร็กทัลไหม? ลองดู แล้วสังเกตว่าการทำซ้ำนั้นให้ผลอะไร
❌ การทดสอบแฟร็กทัล — อันนี้ไม่ผ่าน: โดมจีโอเดสิกไม่ใช่แฟร็กทัล ซูมเข้าไปในเกล็ดหิมะ คุณเจอหนามเพิ่มขึ้นเรื่อยๆ ตลอดไป ซูมเข้าไปในโดม คุณเจอสามเหลี่ยมแบนๆ แล้วก็ไม่มีอะไรอีก — รายละเอียดหมดลง พื้นผิวของมันลู่เข้าหาทรงกลมที่เรียบสนิท ซึ่งมีมิติเท่ากับ 2 พอดี เป็นจำนวนเต็ม ฟุลเลอร์ไม่ได้ไล่ตามความขรุขระ เขาไล่ตามสิ่งตรงข้าม — การประมาณทรงกลมเรียบที่แข็งแรงและประหยัดที่สุดด้วยเสาตรงจำนวนน้อยที่สุด
🧠 ทำไมหัวข้อนี้จึงอยู่ตรงนี้: ทุกอย่างในหน้านี้คือตัวอย่าง มีเพียงหัวข้อนี้ที่เป็นตัวอย่างที่ไม่ใช่ และมันทำงานหนักกว่าตัวอย่างอื่นทั้งหมด เหตุผลมีดังนี้
1. คุณยังไม่เข้าใจคำใด จนกว่าจะชี้ได้ว่ามันกันอะไรออกไป ใครก็พยักหน้ากับประโยค "แฟร็กทัลซ้ำในทุกขนาด" ได้ บททดสอบจริงคือมีคนยื่นสิ่งที่ดูเหมือนควรเข้าข่ายมาให้ แล้วคุณบอกได้ว่าทำไมมันไม่ใช่
2. มันทำลายความเข้าใจผิดที่พบบ่อยที่สุด เกือบทุกคนที่เรียนเรื่องนี้แบบครึ่งๆ กลางๆ จะจากไปพร้อมความเชื่อว่า "สร้างด้วยกฎที่ทำซ้ำ = แฟร็กทัล" โดมคือการหักล้างที่สะอาดที่สุด เพราะมันสร้างด้วยลูปแบบนั้นเป๊ะ — เอาสามเหลี่ยมมาตัด แล้วทำซ้ำ กลไกเดียวกับเกล็ดหิมะ ผลลัพธ์ตรงข้าม
3. มันเปลี่ยนนิยามให้เป็นการทดสอบที่ทำได้จริง "ดูซับซ้อน" เป็นแค่ความรู้สึก แต่ รายละเอียดอยู่รอดในทุกสเกลหรือตายไป? เป็นคำถามที่มีคำตอบ — และในหน้านี้มันเป็นตัวเลข เส้นรอบรูปของเกล็ดหิมะคูณ 4⁄3 ทุกรอบ วิ่งสู่อนันต์ ช่องว่างของโดมลดครึ่งทุกรอบ วิ่งสู่ศูนย์
4. มันคือความต่างเดียวกับที่สำคัญในงานจริง การวนซ้ำจนรายละเอียดหายไป คือสิ่งที่ระเบียบวิธีเชิงตัวเลขและเอนจินกราฟิกทำทุกวัน — ซอยพื้นผิวจนหน้าเล็กกว่าพิกเซล แล้วโมเดลก็เสร็จ ส่วนการวนซ้ำจนรายละเอียดยังอยู่ นั่นคือแฟร็กทัล ลูปเดียวกัน ลิมิตตรงข้าม เครื่องมือคนละชุด
5. มันทำให้หน้านี้ซื่อสัตย์ หัวข้อนี้ดึงดูดตำนานมากกว่าคณิตศาสตร์สาขาไหนๆ — อัตราส่วนทองคำในพาร์เธนอน φ ในหอยงวงช้าง และใช่ โดมจีโอเดสิกก็ถูกเรียกว่า "สถาปัตยกรรมแฟร็กทัล" อยู่บ่อยๆ นิสัยที่ปกป้องคุณคือสิ่งเดิมทุกครั้ง: ถามว่าตัวเลขทำอะไรเมื่อคุณซูมเข้าไป ฟุลเลอร์ก็สมควรได้รับความเคารพนั้น เขาไม่ได้พยายามไล่ตามความขรุขระไม่สิ้นสุดแล้วพลาด เขาแก้ปัญหาตรงข้าม และแก้ได้อย่างงดงาม
🔺 ฟุลเลอร์กำลังหาค่าที่ดีที่สุดของอะไร — และเขารู้ได้อย่างไรว่าคำตอบต้องเป็นสามเหลี่ยม: เหตุผลของเขาเริ่มจากสิ่งที่แทบมองข้าม: สองจุดสร้างรูปทรงไม่ได้ สองจุดให้คุณแค่เส้นตรง — ความยาว ไม่มีอะไรอื่น ไม่มีข้างใน ไม่มีพื้นที่ สามจุดคือจำนวนน้อยที่สุดที่ล้อมอะไรได้ สามเหลี่ยมจึงไม่ใช่แค่รูปทรงที่ดี แต่เป็นรูปทรงแรกที่มีอยู่ได้
แล้วข้อเท็จจริงที่สองทำงานจริง: สามเหลี่ยมเป็นรูปหลายเหลี่ยมเดียวที่ผลักให้เสียรูปไม่ได้ เอาแท่งสี่แท่งต่อเป็นสี่เหลี่ยมด้วยหมุดหลวมที่มุม แล้วดันด้านข้าง — มันจะเอียงเป็นรูปข้าวหลามตัด โดยไม่มีแท่งไหนเปลี่ยนความยาวเลย ทำอย่างเดียวกันกับสามเหลี่ยม ไม่มีอะไรเกิดขึ้น: จะขยับได้ต้องทำให้ด้านใดยาวขึ้นหรือสั้นลงจริงๆ ความแข็งของสามเหลี่ยมมาจากเรขาคณิตของมัน ไม่ใช่จากข้อต่อที่แข็ง รูปหลายเหลี่ยมอื่นทุกรูปต้องมีค้ำยัน — และค้ำยันที่คุณเพิ่มก็คือสามเหลี่ยมเสมอ
ฟุลเลอร์ดันเหตุผลเดียวกันขึ้นไปอีกมิติ: ถ้าสามจุดคือจำนวนน้อยที่สุดที่ล้อมพื้นที่ สี่จุดก็คือจำนวนน้อยที่สุดที่ล้อมปริมาตร — ทรงสี่หน้า ซึ่งเขาเรียกว่าระบบที่เล็กที่สุดในเอกภพ และใช้เป็นรากฐานของ synergetics ทั้งหมดของเขา จากจุดนั้นโดมเกือบจะเป็นข้อสรุปที่เลี่ยงไม่ได้: ทรงกลมบรรจุปริมาตรมากที่สุดด้วยพื้นผิวน้อยที่สุด สามเหลี่ยมเป็นแผงเดียวที่รักษารูปได้เองโดยไม่ต้องช่วย ดังนั้น — ประมาณทรงกลมด้วยสามเหลี่ยมทั้งหมด แล้วคุณจะได้พื้นที่ใช้สอยมากที่สุด ด้วยวัสดุน้อยที่สุด และไม่ต้องค้ำยันที่ใดเลย เขาเสนอว่านี่เป็นโครงสร้างชนิดเดียวที่ยิ่งสร้างใหญ่ ยิ่งแข็งแรงขึ้นเมื่อเทียบกับน้ำหนักตัว
และนั่นคือเหตุผลที่มันไม่ใช่แฟร็กทัลพอดี ดูว่าเขาลดอะไรให้น้อยที่สุด: จำนวนชิ้นส่วน ฟุลเลอร์ต้องการเสาน้อยที่สุดเท่าที่จะทำงานได้ และการซอยเพิ่มทุกครั้งคือต้นทุนที่เขาจ่ายเพื่อเข้าใกล้ความเรียบ ส่วนแฟร็กทัลต้องการสิ่งตรงข้าม — ต้องการให้รายละเอียดมาเรื่อยๆ ตลอดไป ในทุกสเกล สองการออกแบบ ลูปตัดสามเหลี่ยมเดียวกัน แต่เป้าหมายตรงข้าม: อันหนึ่งใช้การวนซ้ำเพื่อทำให้ความขรุขระหายไป อีกอันเพื่อให้แน่ใจว่ามันไม่หายไปเลย
ประโยคเดียวที่ควรจำกลับไป: แฟร็กทัลไม่ได้นิยามด้วยวิธีสร้าง แต่ด้วยสิ่งที่ยังเหลืออยู่เมื่อคุณมองใกล้ขึ้น ทำซ้ำแล้วรายละเอียดตายไป คุณได้โดม ทำซ้ำแล้วรายละเอียดยังมาเรื่อยๆ คุณได้แฟร็กทัล
⚙️ ผลตอบแทนที่ใช้ได้จริง: การคิดเป็นแพตเทิร์นให้ประสิทธิภาพ และให้ไม้วัดสำหรับการปรับปรุง ถึงคุณจะไม่วาดเกล็ดหิมะอีกเลย วิธีคิดแบบนี้ก็ยังคุ้มที่จะเรียน เพราะมันให้สองสิ่งที่หาจากที่อื่นได้ยาก
1. แพตเทิร์นหนึ่งอันแทนรายการทั้งชุด — นั่นคือประสิทธิภาพล้วนๆ ดูสิ่งที่หน้านี้เก็บไว้จริงๆ: ต้นไม้ที่ความลึก 12 วาด 4,095 เส้น แต่คำอธิบายทั้งหมดของมันคือตัวเลขสี่ตัวกับกฎหนึ่งประโยคที่พูดออกมาได้ เกล็ดหิมะโคชไปถึง 3,072 ด้าน จากโค้ดไพทอนราวสิบบรรทัด เมล็ดพืชเก็บแผนที่ของทุกใบไม่ได้ แต่เก็บกฎได้สบาย เมื่อคุณเห็นว่าสิ่งใหญ่ประกอบด้วยสำเนาเล็กๆ ของตัวมันเอง คุณจะเลิกไล่เขียนชิ้นส่วน แล้วหันไปเขียนกฎ — สิ่งที่ต้องเก็บ ส่ง จำ หรือดีบั๊ก จึงยุบจากหลายพันรายการเหลือหนึ่ง
นี่ไม่ใช่อุปมาของการเขียนโปรแกรม มันคือการเขียนโปรแกรม การสังเกตว่าปัญหาหนึ่งมีเวอร์ชันเล็กของตัวเองอยู่ข้างใน คือสิ่งที่เปลี่ยนวิธีแก้ที่ช้าให้เร็ว: เรียงข้อมูลหนึ่งล้านรายการด้วยการแบ่งครึ่งซ้ำๆ ใช้งานราวหนึ่งในล้านของการเทียบทุกคู่ เกมสร้างภูมิประเทศทั้งผืนจากเลขเมล็ดพันธุ์แทนที่จะแนบมาในไฟล์ เอนจินกราฟิกซอยพื้นผิวจนรายละเอียดเล็กกว่าพิกเซลแล้วหยุด ทุกครั้งคือข้อคิดเดียวกัน — หาโครงสร้างที่คล้ายตัวเอง แล้วเขียนกฎ ไม่ใช่เขียนรายการ
2. การมีสิ่งที่จับต้องได้ไว้เปรียบเทียบ ทำให้คุณปรับปรุงกระบวนการซับซ้อนได้ทีละขั้น นี่คือสิ่งที่โดมสาธิตอย่างเงียบๆ วงกลมเส้นประคือเป้าหมาย และค่า gap คือตัวเลขที่บอกว่าคุณยังห่างแค่ไหน: 20.5%, 6.6%, 1.8%, 0.45% คุณไม่ต้องเถียงว่ารูปทรง "ดีขึ้น" หรือยัง — วัดได้เลย ตัดสินใจได้ว่ารอบต่อไปคุ้มกับสามเหลี่ยมอีก 960 ชิ้นไหม และหยุดเมื่อไม่คุ้ม นั่นคือลูปทางวิศวกรรมทั้งวง: เปลี่ยนหนึ่งอย่าง วัดเทียบกับจุดอ้างอิงคงที่ เก็บไว้หรือทิ้ง แล้วทำซ้ำ
สังเกตว่าหน้านี้สร้างขึ้นแบบนั้นมากแค่ไหน ไม่ใช่ "เกล็ดหิมะขรุขระขึ้น" แต่เป็น ×4⁄3 ของเส้นรอบรูปทุกรอบ ไม่ใช่ "ขอบมานเดลบรอตซับซ้อน" แต่เป็น มิติ 2 ไม่ใช่ "โดมดูเรียบพอแล้ว" แต่เป็น 0.45% แต่ละอันเปลี่ยนเรื่องความเห็นให้เป็นเรื่องที่ตรวจสอบได้ — และเมื่อตรวจสอบได้ ก็ปรับปรุงได้อย่างตั้งใจ ไม่ใช่ด้วยโชค การคิดเป็นแพตเทิร์นให้กฎเล็กๆ แก่คุณ ส่วนไม้วัดที่จับต้องได้บอกว่าการทำซ้ำนั้นพาคุณไปข้างหน้าจริงหรือไม่
✓ Check yourself — the dome
令人意外的是:分形不是一幅又长又复杂的图,而是一条简短的规则,被反复遵守。下面这棵树的规则只有:“画一条线。在它的顶端,长出两棵更小的树,各自稍微偏向两侧。当树太小时就停下。”
最后一句和第一句同样重要。“当……就停下”就是基准情形(base case);没有它,规则会永远运行下去,什么也画不出来。每一个递归都需要一个停下来的办法。
所以分形有两副面孔,又是我们的两种心智:列清单的人能把规则写成一行里的四个数字 🌍;聆听的人看见一整棵活着的树 🌏。同一个东西——一个清点它,一个感受它。
🎛️ 四个数字:转角=每根子枝偏离父枝多少(小=细高的植物;大=张开的扇形;试试 2° 再试 72°)。收缩=必须小于 1,否则树永不停止;接近 0.5 树梢很快消失,接近 0.85 枝条纠缠在一起;0.618 就是 1÷φ(上一节的黄金比例)。深度=规则允许调用自己几次;每 +1,树梢就翻一倍。分枝数=每个顶端生几个孩子(2=树;5=雪花或烟花);总量是分枝数^深度,5⁶ 已经是 15,625 条线。
请注意:代码里没有任何"树"的代码——没有树干清单,也没有叶子清单。
branch 只知道画一条线,然后向自己要两棵更小的树。这就是递归(递归):一条用到自己的规则。树就是递归的样子。按"🔍 显示里面的小树":一根子枝变成紫色——它就是同一棵树,只是更小。这叫自相似(自相似),也正是全部的重点:整体的图案存在于每一个部分之中。
สิ่งที่น่าประหลาดใจ: แฟร็กทัลไม่ใช่ภาพวาดที่ยาวและซับซ้อน แต่เป็นกฎสั้นๆ ข้อเดียวที่ทำซ้ำแล้วซ้ำอีก กฎของต้นไม้ข้างล่างมีเพียง: “ลากเส้นหนึ่งเส้น ที่ปลายเส้นให้เริ่มต้นไม้เล็กสองต้น เอียงออกข้างละนิด หยุดเมื่อต้นไม้เล็กเกินไป”
ประโยคสุดท้ายสำคัญเท่าประโยคแรก “หยุดเมื่อ…” คือ กรณีฐาน (base case) ถ้าไม่มีมัน กฎจะทำงานไปตลอดกาลและไม่มีอะไรปรากฏเลย ทุกการเรียกซ้ำต้องมีวิธีหยุด
แฟร็กทัลจึงมีสองใบหน้า และมันคือสองจิตของเราอีกครั้ง: คนทำรายการเขียนกฎเป็นตัวเลขสี่ตัวในบรรทัดเดียว 🌍 ส่วนผู้ฟังเห็นต้นไม้ที่มีชีวิตทั้งต้น 🌏 — สิ่งเดียวกัน คนหนึ่งนับมัน คนหนึ่งรู้สึกถึงมัน
🎛️ ตัวเลขสี่ตัว: มุม = แต่ละกิ่งลูกเอนออกจากกิ่งแม่เท่าไร (น้อย = ต้นสูงชะลูด, มาก = พัดกางออก; ลอง 2° แล้วลอง 72°) การหด = ต้องน้อยกว่า 1 ไม่งั้นต้นไม้ไม่มีวันหยุดโต; ใกล้ 0.5 กิ่งย่อยหายไว, ใกล้ 0.85 กิ่งยาวและพันกัน; 0.618 คือ 1÷φ อัตราส่วนทองคำจากหัวข้อก่อนหน้า ความลึก = กฎเรียกตัวเองได้กี่ครั้ง ทุก +1 ปลายกิ่งเพิ่มเป็นสองเท่า จำนวนกิ่ง = แต่ละปลายแตกลูกกี่กิ่ง (2 = ต้นไม้, 5 = เกล็ดหิมะหรือพลุ) รวมเป็น จำนวนกิ่ง^ความลึก — 5⁶ ก็ 15,625 เส้นแล้ว
สังเกตว่าในโค้ดไม่มีโค้ดของ “ต้นไม้” อยู่เลย ไม่มีรายการลำต้น ไม่มีรายการใบ
branch รู้แค่วิธีวาดหนึ่งเส้น แล้วขอตัวเองให้สร้างต้นไม้เล็กสองต้น นั่นคือการเรียกซ้ำ (recursion): กฎที่ใช้ตัวเอง ต้นไม้คือหน้าตาของการเรียกซ้ำกด “🔍 แสดงต้นไม้เล็กข้างใน”: กิ่งย่อยหนึ่งกลายเป็นสีม่วง — และมันคือต้นไม้เดียวกันอีกครั้ง เพียงเล็กกว่า นี่คือความคล้ายตัวเอง (self-similarity) และเป็นประเด็นทั้งหมด: ลวดลายขององค์รวมอยู่ในทุกส่วน