Sự cần thiết của hình học Fractal Hình học là ngôn ngữ đặc biệt để mô phỏng tự nhiên, và hình học Euclide đã ngự trị một thời gian dài trong lĩnh vực mô tả, xử lý các hình dạng của tự nh
Trang 1Cho; }
Mhvanban;
END
Chương VI Hình học Fractal
I Sự cần thiết của hình học Fractal
Hình học là ngôn ngữ đặc biệt để mô phỏng tự nhiên, và hình học Euclide đã ngự trị một thời gian dài trong lĩnh vực mô tả, xử lý các hình dạng của tự nhiên Tuy nhiên trong thế giới thực có một lớp hình dạng không dễ dàng được mô tả bởi hình học Euclide như: núi, mây, trời, biển Đặc tính của những đối tượng này là khi phóng to một phần chi tiết
nào đó thì sẽ có được dạng lặp lại của toàn hình, đặc tính đó được gọi là tự tương tự (self- similarity) Hình học Fractal (viết tắt của Fractional – phân đoạn) ra đời để thích nghi với
việc mô phỏng lớp hình dạng đó: lớp hình có đặc tính “Fractal” – tự tương tự (Xem và chạy thử file fractal.exe)
Đường cong Fractal không thể được mô tả như đường hai chiều thông thường, mặt
Fractal không thể mô tả như mặt 3 chiều mà đối tượng Fractal có thêm chiều hữu tỷ Mặc dù
các đối tượng Fractal trong từng trường hợp cụ thể chỉ chứa một số hữu hạn chi tiết, nhưng
nó chứa đựng bản chất cho phép mô tả vô hạn chi tiết, tức là tại một thời điểm xác định thì
là hữu hạn, nhưng xét về tổng thể là vô hạn vì bản chất Fractal cho phép phóng đại lên một mức độ bất kỳ một chi tiết tùy ý
Hiện nay hình học Fractal và các khái niệm của nó đã trở thành công cụ trung tâm trong các lĩnh vực của khoa học tự nhiên như: vật lý, hóa học, sinh học, địa chất học, khí tượng học, khoa học vật liệu
Để hiểu thế nào là hình học Fractal, ta hãy so sánh với hình học Euclide cổ điển
1) Xuất hiện từ rất lâu, trên 2000 năm trước 1) Xuất hiện năm 1975 (năm nhà toán học
Benoit Mandelbrot công bố công trình về tập Mandelbrot)
2) Vật thể hình học Euclide có kích thước
đặc trưng
2) Không có kích thước xác định
3) Thích hợp với việc mô tả những thực thể
được tạo ra bởi con người
3) Thích hợp để mô tả những vật thể trong
tự nhiên 4) Được mô tả bởi công thức (phương trình
tham số, phương trình bề mặt, quỹ đạo
)
4) Được mô tả bởi thuật toán lặp
Hình học Euclide cho sự mô tả gọn gàng, chính xác những vật thể được tạo bởi con người (khối lập phương, mặt trụ, mặt cầu ) nhưng không thích hợp khi dùng để mô tả những hình dạng tự nhiên vì đòi hỏi một khối lượng tính toán (số và bậc của phương trình, ố lượng biến ) rất cồng kềnh mà vẫn không chính xác Còn sự mô tả của hình học Fractal (các thuật lặp) lại đặc biệt thích hợp với việc tạo sinh bằng máy tính Thực thể Fractal là kết quả của một quá trình lặp theo một thuật toán xác định, được tạo sinh lý tưởng bằng máy tính và rất khó được tạo một cách thủ công
Trang 2II Một số khái niệm cơ bản
Các thực thể Fractal có 3 đặc tính quan trọng:
• Tự tương tự (self-similarity)
• Tự tương tự đa phần (statistical self-similarity)
• Tự Affine
Chúng ta chỉ khảo sát đặc tính đầu tiên và quan trọng nhất: đặc tính tự tương tự
(self-similarity)
Một thực thể có đặc tính tự tương tự nếu nó là hợp của N tập con không giao nhau, mỗi tập con được tạo sinh từ tập gốc qua các phép biến đổi như: co dãn, dịch chuyển, quay Phát biểu một cách hình thức hơn, xét tập S gồm những điểm:
x = (x1, x2, xE) trong không gian E chiều
Dưới phép đồng dạng với hệ số co 0 < T < 1, tập S biến thành tập TS với những điểm:
Tx = (Tx1, Tx2, TxE)
Tập S là tự tương tự nếu S là hợp của N tập con không giao nhau, mỗi tập con tương đương với TA (có thể sai khác một phép tịnh tiến, quay hoặc vị tự) Khi đó số chiều của S được định nghĩa bởi
T
N D
1 log
log
=
Tập S cũng được gọi là tự tương tự nếu các tập con được tạo sinh từ tập gốc theo các hệ số
co Ti khác nhau Trong trường hợp này số chiều D được tính từ công thức sau
1 1
=
∑
=
N i
D i
T
III Ví dụ minh họa
Ta hãy xét một ví dụ minh họa tính tự tương tự của một thực thể Fractal kinh điển: đường Von-Koch Đường Von- Koch (còn gọi là “Bông hoa tuyết Von-Koch” như trong
Wikipedia) là một trong những đường Fractal được công bố sớm nhất, vào năm 1904 bởi nhà toán học Thụy Điển Helge Von Koch Thuật toán lặp cho đường Von-Koch gồm những bước sau:
a) Một đoạn thẳng cho trước được chia làm 3 phần bằng nhau
b) Đoạn giữa được thay bởi 2 đoạn có chiều dài tương đương
c) Mỗi đoạn trong số 4 đoạn này lại được thay bởi 4 đoạn mới có chiều dài bằng 1/3 đoạn trước
d) Quá trình cứ thế lặp lại
Trang 3Đặc điểm của đường Von-Koch
• Đường cong này có tính tự tương tự, mỗi phần nhỏ khi được phóng to có thể tạo sinh lại giống như phần lớn hơn, nói cách khác nó bất biến dưới sự phóng to hình
• Qua mỗi bước lặp, độ dài đường von-Koch tăng lên 4/3 lần
• Đường cong (sau vô hạn bước) có độ dài vô hạn mặc dù nó chỉ chiếm một phần diện tích hữu hạn của mặt phẳng
• Không tự cắt
• Thuật toán tạo sinh đường Von-Koch khá đơn giản, nhưng không có công thức đại số
để xác định những điểm trên đường cong
• Số chiều của đường Von-Koch là hữu tỷ:
26 , 1 ) 3 log(
) 4 log(
1 log
⎟
⎠
⎞
⎜
⎝
⎛
=
T
N D
a)
b)
c)
Trang 4D phản ánh mức độ lan tỏa của đường cong Khi D biến thiên từ 1 đến 2, đường cong biến thiên từ đường thẳng lan dần đến lấp đầy mặt phẳng hơn
Số bước lặp Độ dài phân đoạn Số phân đoạn Tổng chiều dài đường Koch
100 1/1.71e+47 4.02e+59 2338486807656.00
Chương trình vẽ đường Von-Koch
{ Vẽ 3 đường Von Koch giáp nhau tạo thành hình bông tuyết}
Uses crt,graph;
{ hệ số đổi từ độ sang radian }
Const
RADS = 0.017453293;
Var
i,gd,gm:integer;
temp:real;
Procedure Koch(dir:integer; len:real; n:integer);
Trang 5Begin
if (n>0) then
begin
Koch(dir, len / 3, n-1);
dir := dir + 60;
Koch(dir, len / 3, n-1);
dir := dir - 120;
Koch(dir, len / 3, n-1);
dir := dir + 60;
Koch(dir, len / 3, n-1);
end
else
linerel(round(len * cos(RADS * dir)), round(len * sin(RADS * dir)));
End;
Begin
gd:=detect;
initgraph(gd,gm,'');
for i:=1 to 4 do
begin
setcolor(White);
rectangle(0, 0, getmaxx, getmaxy);
moveto(100,350); Koch(0, 420 , i);
setcolor(blue); Koch(-120, 420 , i);
setcolor(yellow); Koch(120, 420 , i);
readln;
cleardevice;
end;
closegraph;
End
Đường Hilbert do nhà toán họa Đức David Hilbert công bố năm 1891 Độ dài của nó tại
bước lặp thứ n là
n
n n
L
2
1
2 −
=
tức là độ dài tăng theo hàm mũ đối với n
Trang 6Quay 900 thì như nhau
Cả 4 quy tắc (rules) thực chất chỉ là 1
Trang 7Chương trình vẽ đường Hilbert
{Vẽ các đường Hilbert}
Uses Crt,Graph;
Var
gd,gm,h:integer;
Procedure A (i:integer);FORWARD;
Procedure B (i:integer);FORWARD;
Procedure C (i:integer);FORWARD;
Procedure D (i:integer);FORWARD;
Procedure A(i:integer);
Begin
if (i>=0) then
Begin
D(i-1); linerel(-h, 0);
A(i-1); linerel(0, -h);
A(i-1); linerel(h, 0);
B(i-1);
End;
End;
Procedure B(i:integer);
Begin
if (i>=0) then
Begin
C(i-1); linerel(0, h);
B(i-1); linerel(h, 0);
B(i-1); linerel(0, -h);
A(i-1);
End;
End;
Procedure C(i:integer);
Begin
Trang 8if (i>=0) then
Begin
B(i-1); linerel(h, 0);
C(i-1); linerel(0, h);
C(i-1); linerel(-h, 0);
D(i-1);
End;
End;
Procedure D(i:integer);
Begin
if (i>=0) then
Begin
A(i-1); linerel(0, -h);
D(i-1); linerel(-h, 0);
D(i-1); linerel(0, h);
C(i-1);
End;
End;
Procedure Hilbert;
Var
i:integer;
Begin
for i:=0 to 5 do
begin
h:= 30 - 5 * i;
moveto(getmaxx - 130, getmaxy - 50);
A(i);
readln; cleardevice;
end;
End;
Begin
gd:=detect;
initgraph(gd,gd,'');
setcolor(YELLOW);
rectangle(0, 0, getmaxx, getmaxy);
Hilbert;
closegraph;
End
Trang 9Chương trình vẽ Nhân sư (Sphinx)
{ Vẽ con nhân sư Sphinx }
Uses Crt,Graph;
{ hệ số đổi từ độ sang radian }
Const
RADS = 0.017453293;
Var
curangle,curx, cury:real;
gd,gm:integer;
Procedure lineforward(angle, length:real);
Begin
curangle :=curangle+ angle;
curx := curx + length*cos(curangle*RADS);
cury := cury + length*sin(curangle*RADS);
lineto(round(curx), round(cury));
End;
Procedure moveforward(angle,length:real);
Begin
curangle := curangle + angle;
curx := curx + length*cos(curangle*RADS);
cury := cury + length*sin(curangle*RADS);
lineto(round(curx), round(cury));
End;
Trang 10Procedure Sphinx(angle, length: real; level,leftright:integer);
Var
len4, len2, len1, oldx, oldy, oldangle: real;
Begin
if (leftright<>0) then
Begin
if (level = 0) then
begin
len1 := length / 3;
lineforward(angle, length);
lineforward(-120,len1*2);
lineforward(-120,len1);
lineforward(+60,len1);
lineforward(-60,len1);
end
else
begin
Sphinx(angle, length, 0, leftright);
len4 := length / 4;
Sphinx(240, len4, 0, 1);
moveforward(240, len4);
Sphinx(0, len4, 0, 1);
moveforward(240, len4);
Sphinx(0, len4, 0, 1);
moveforward(240, len4);
Sphinx(0, len4, 0, 1);
moveforward(240, len4);
moveforward(-120, len4*2/3);
Sphinx(0, len4, 0, 0);
moveforward(240, len4);
Sphinx(0, len4, 0, 0);
moveforward(-180, len4*2/3);
Sphinx(-120, len4, 0, 0);
moveforward(240, len4/3);
Sphinx(-240, len4, 0, 1);
moveforward(240, len4);
Sphinx(0, len4, 0, 1);
moveforward(240, len4);
Sphinx(-60, len4, 0, 0);
moveforward(-180, len4*2/3);
lineforward(-60, len4);
moveforward(60, len4/3);
moveforward(-120, len4);
Sphinx(-180, len4, 0, 0);
end;
end
else
begin
Trang 11if (level = 0) then
begin
len1 := length / 3;
lineforward(angle, length);
lineforward(-120,len1);
lineforward(-60,len1);
lineforward(60,len1);
lineforward(-120,len1*2);
end
else
begin
Sphinx(angle, length, 0, leftright);
len4 := length / 4;
end;
end;
End;
Begin
curangle := 0.0;
gd:=detect;
initgraph(gd,gm,'');
moveto(10, 470);
curx := 10;
cury := 470;
Sphinx(0, 600, 1, 1);
readln;
closegraph;
End
Chương trình vẽ Phong cảnh (Fractal.exe)
Uses crt,graph;
Const
CLIP_ON = 1;
Var
n,c,t,mau:integer;
hs,go:real;
i,gd,gm:integer;
ch:char;
Function dau:integer;
Begin
if (random(2) = 0) then
dau:= -1
else
dau:= 1;
End;
Procedure cay(x,y:integer; h,g,gw:real; k:integer);
Trang 12Var
x1,y1,i,j,d,leaf,c:integer;
dg,tt:real;
Begin
if (k > 0) then
for j:= 1 to (random(t) + t) do
x1:= x + round(h * cos(g));
y1:= y + round(h * sin(g));
setcolor(DARKGRAY);
for i:= 0 to round((h/35)*(h/35)) do
begin
line(x + i, y, x1 + i, y1);
delay(10); {Ve cay cham de quan sat }
for d:= 1 to round((h/5)) do begin
putpixel(round((1-tt)*x+tt*x1+i),
round((1-tt)*y+tt*y1), LIGHTGRAY);
end;
end;
dg := gw/(2*n+1);
for i:= -n to n do
if (random(1000)*0.001 > 0.5) then
cay(x1,y1,h*(0.5+(random(1000)*0.001)/3),g+i*dg,gw*hs,k-1);
x := x1;
y := y1;
g := g + PI/18;
else
begin
setfillstyle(1,random(15));
setcolor(random(15));
for leaf:= 1 to 2 do
fillellipse(x+random(8)*dau,y+random(5)*dau,random(5)+2,random(2)+1); for leaf:= 1 to 70 do
begin
case leaf of
0 20:
begin putpixel(x+random(15)*dau,y+random(5)*dau,BLUE);
end;
21 25:
begin putpixel(x+random(15)*dau,y+random(5)*dau,LIGHTBLUE);
end;
Trang 1326 49:
begin putpixel(x+random(15)*dau,y+random(5)*dau,LIGHTGREEN);
end;
End;
End;
End;
End;
Procedure cloud(x,y:integer; Rx,Ry:real; k:integer);
Var
i:integer;
Begin
if (k > 0) then
for i:= 1 to 5 do
cloud(x+random(round(Rx)),y+random(round(Ry)),Rx*0.8,Ry*0.6,k-1)
else
for i:= 1 to round(sqrt(Rx*Ry)/3.5) do
putpixel(x+random(round(Rx)),y+random(round(Ry)),WHITE);
End;
Procedure phong;
Var
l,i:integer;
Begin
l := (getmaxy div 7) * 5;
mau:=random(15);
setfillstyle(1,mau);
bar(0,0,getmaxx,l);
setfillstyle(1,LIGHTGRAY);
bar(0,l,getmaxx,getmaxy);
for i:= 1 to 20000-1 do
case (random(8)) of
0 4:
begin
putpixel(random(getmaxx),l+random(getmaxy-l),GREEN);
break;
end;
5,6:
begin
putpixel(random(getmaxx),l+random(getmaxy-l),YELLOW);
break;
end;
7:
begin
putpixel(random(getmaxx),l+random(getmaxy-l),LIGHTRED);
break;
end;
Trang 14end;
if (mau<>RED) then
Begin
if (mau<>BLACK) then
begin
setfillstyle(1,RED);
setcolor(RED);
end;
end
else
begin
setfillstyle(1,YELLOW);
setcolor(YELLOW);
end;
fillellipse(random(getmaxx div 2)+300,100,30,30);
for i:= 1 to 5 do
cloud(random(getmaxx),random(150)+10,random(60)+60,random(40)+20,5);
End;
BEGIN
randomize;
gd:=detect;
initgraph(gd,gm,'');
setviewport(0,0,getmaxx,getmaxy,CLIPON);
repeat
n := 1;
hs := 1.2;
go := PI /2.8;
t := 2;
phong;
cay(((getmaxx-100) div 5)+random(60),(getmaxy div 7)*6
+random(30)*dau,getmaxy div 6,-PI/2,go,5);
ch:=readkey;
until (ch=#27);
closegraph;
END
Trang 15Chương trình vẽ cây Pytago
{ Cây Pythagoras }
Uses Crt,Graph;
Const
{ 1 / sqrt(2) }
FCT = 0.7071067;
{ he so doi tu do sang radian }
RADS = 0.017453293;
Var
gd,gm:integer;
Procedure quadrat(x,y,a,angle:real);
Var
cp,sp:real;
Begin
setcolor(RED);
if (a < 35) then
setcolor(2);
if (a < 8) then
setcolor(7);
cp := a * cos(angle);
sp := a * sin(angle);
line(round(x), 200 - round(y), round(x + cp), 200 - round(y+sp));
line(round(x), 200 - round(y), round(x - cp), 200 - round(y+cp));
line(round(x+cp), 200 - round(y+sp), round(x - sp + cp), 200 - round(y+sp+cp));
line(round(x-sp), 200 - round(y+cp), round(x - sp + cp), 200 - round(y+sp+cp));
if (a > 2) then
Begin
quadrat(x - sp, y + cp, 3 * a / 5, angle + 0.93);
quadrat(x - sp + 3 * a / 5 * cos(angle + 0.93),
y + cp + 3 * a / 5 * sin (angle + 0.93), a * 4 / 5,
angle - 0.64);
Trang 16End;
End;
Begin
gd:=detect;
initgraph(gd,gm,'');
setcolor(7);
quadrat(250, -120, 70, 0);
readln;
closegraph;
End