9.4.3.1. Xõy dựng thuật toỏn:
Tập Mandelbrot là hỡnh ảnh của dóy (zn), với giỏ trị khởi đầu z0 = 0. Khi đú màn hỡnh mỏy tớnh sẽ chuyển đổi thành một mặt phẳng phức thu hẹp với:
Trục x biểu diễn phần thực của số phức c (giỏ trị p được nờu ở phần 2/). Trục y biểu diễn phần ảo của số phức c (giỏ trị q được nờu ở phần 2/).
Từ tớnh chất về sự hội tụ của dóy (zn) ở phần 2 chỳng ta cú thể chia tập cỏc giỏ trị
của c trờn mặt phẳng phức thành 2 lớp: Lớp 1:
Gồm cỏc giỏ trị c làm cho dóy (zn) khụng tiến ra vụ cực mà được giới hạn trong một vũng trũn bỏn kớnh 2. Một cỏch cụ thể, đú là cỏc giỏ trị c sao cho khi xuất phỏt từ chỳng, ta luụn cú | zi | < 2, ∀i = 1, 2, …, l, trong đú l do ta chọn trước. Để ý là giỏ trị l càng lớn thỡ tớnh hội tụ của dóy (zn) tương ứng với một giỏ trị cụ thể càng được kiểm tra chặt chẽ và chớnh xỏc. Tuy nhiờn khi đú thời gian tớnh toỏn để xỏc định tớnh hội tụ sẽ tăng lờn gấp nhiều lần.
Lớp 2:
Gồm cỏc giỏ trị phức c làm cho dóy (zn) hội tụ về vụ cực. Cụ thể đú là cỏc giỏ trị c khởi đầu dẫn đến | zn | > 2 ở một ngưỡng k hữu hạn nào đú.
Vấn đề đặt ra ở đõy là cần quan sỏt tớnh hỗn độn của dóy (zn). Do đú chỳng ta tập trung cỏc quan sỏt vào cỏc giỏ trị c thuộc lớp 2. Muốn như vậy cỏc giỏ trị này phải được thực hiện một cỏch nổi bật trờn màn hỡnh mỏy tớnh bởi cỏc màu khỏc nhau. Chỳng ta sẽ tụ màu mặt phẳng phức màn hỡnh theo qui tắc sau:
Cỏc giỏ trị c thuộc lớp 1 được tụ màu đen vỡ khụng cú tớnh chất gỡ đỏng chỳ ý. Cỏc giỏ trị c thuộc lớp 2 được tụ bằng cỏc màu khỏc nhau ứng với cỏc ngưỡng tiến ra vụ hạn k khỏc nhau. Do số lượng màu cú thể hiển thị trờn một màn hỡnh đồ hoạ
là hữu hạn, việc tụ màu cỏc giỏ trị này sẽđược thực hiện theo kỹ thuật tụ màu xoay vũng được chỉ ra ở cỏc phần tiếp sau đõy.
9.4.3.2. Thuật toỏn tổng quỏt để thể hiện tập Mandelbrot:
Thuật toỏn gồm cỏc bước sau: Bước 1:
Xuất phỏt với một giỏ trị khởi đầu c = (p,q). Bước 2:
Kiểm tra c thuộc lớp 1 hay lớp 2. Bước 3:
Nếu c thuộc lớp 1 thỡ tụ điểm ảnh tương ứng với c trờn màn hỡnh bằng màu đen, ngược lại tụ điểm ảnh này bởi màu tương ứng xỏc định từ kỹ thuật tụ xoay vũng.
Bước 4:
Chọn một giỏ trị c mới và trở lại bước 1 cho đến khi quột hết toàn bộ giỏ trị c cần khảo sỏt (đụi khi chỳng ta khụng cần khảo sỏt toàn bộ mà chỉ khảo sỏt một miền con được yờu cầu của mặt phẳng phức). Khi đú thuật toỏn kết thỳc.
Hỡnh 9.11 tập Mandelbrot 9.5. TẬP JULIA
9.5.1. Đặt vấn đề:
Đối với biểu thức zn+1 = zn2 + c, ngoài hướng đó khảo sỏt nhưđó trỡnh bày trong phần tập Mandelbrot, cũn cú hướng khảo sỏt khỏc bằng cỏch cho c cốđịnh và xem xột dóy (zn) ứng với mỗi giỏ trị khỏc của z0. Theo hướng này chỳng ta sẽ thu được 1 lớp cỏc đối tượng fractal mới được gọi là tập Julia.
Tập Julia và tập Mandelbrot là hai lớp cỏc đối tượng fractal cú mối liờn hệ rất chặt chẽ với nhau. Một tớnh chất đỏng chỳ ý là tập Mandelbrot cú thể xem như một loại “bản
đồ” Mandelbrot cú thể cho ra cỏc dạng tập Julia đầy sức lụi cuốn. Cỏc vị trớ như vậy được quan sỏt thấy ở gần biờn của tập Mandelbrot. Nhất là gần cỏc chỏm nhọn. Ngoài ra khi phúng to một phần của tập Mandelbrot, ta sẽ thu được một hỡnh rất giống với tập Julia
được tạo bởi giỏ trị của tõm phần được phúng to.
9.5.2. Cụng thức toỏn học:
Để thể hiện tập Julia trờn màn hỡnh mỏy tớnh, ta vẫn sử dụng cỏc cụng thức như trong phần tập Mandelbrot, như là:
xn+1 = xn2 – yn2 + p yn+1 = 2xnyn + q
Ngoài ra cỏc tớnh chất đó nờu về giới hạn của dóy (z0) vẫn được sử dụng cho tập Julia.
9.5.3. Thuật toỏn thể hiện tập Julia
Điểm khỏc biệt so với tập Mandelbrot ở đõy là giỏ trị p và q được giữ cố định, mặt phẳng màn hỡnh biến đổi thành mặt phẳng phức thu hẹp biểu diễn cỏc giỏ trị của x0 với:
Trục x biểu diễn phần thực của số phức z0. Trục y biểu diễn phần ảo của số phức z0.
Ngoài ra cũn cú sự phõn lớp cỏc giỏ trị của z0 như sau: Lớp 1:
Bao gồm cỏc giỏ trị (z0) cú | zk | < 2, với 0 ≤ k ≤ N trong đú N là hằng số hữu hạn. Tức là lớp 1 gồm cỏc giỏ trị z0 làm cho dóy (z0) khụng tiến ra vụ cực.
Lớp 2:
Bao gồm cỏc giỏ trị (z0) cú | zn | > 2, với n ≥ k, k ∈ Z+, tức là gồm cỏc giỏ trị làm cho dóy (zn) tiến ra vụ cực.
Ngược lại với tập Mandelbrot, khi thể hiện tập Julia trờn màn hỡnh, chỳng ta quan tõm đến cỏc giỏ trị z0 làm cho dóy (zn) khụng hội tụđến vụ cực. Do đú kỹ thuật tụ màu của tập Julia vẫn là kỹ thuật xoay vũng nhưng hoàn toàn ngược lại với kỹ thuật tụ màu tập Mandelbrot. Trong kỹ thuật tụ màu này:
Cỏc điểm ảnh tương ứng với cỏc giỏ trị z0 thuộc lớp 1, sẽđược gỏn màu tựy thuộc độ
lớn của | zl| với l là ngưỡng quyết định hội tụ của dóy (zn) đó nờu trong định nghĩa về lớp 1.
Cỏc điểm ảnh tương ứng với giỏ trị z0 thuộc lớp 2 sẽ được gỏn màu trựng với màu nền của bảng màu đang sử dụng.
Với cỏc thay đổi như vậy, tập Julia sẽđược thể hiện bằng thuật toỏn trỡnh bày như
sau:
Thuật toỏn tổng quỏt để thể hiện tập Julia:
Gồm cỏc bước sau: Bước 1:
Xuất phỏt với 1 giỏ trị khởi đầu z0 = (x0, y0) và giỏ trị cốđịnh c = (p, q). Bước 2:
Kiểm tra z0 thuộc lớp 1 hay 2. Bước 3:
Tụ màu điểm ảnh tương ứng với z0 theo kỹ thuật tụ màu được nờu ở trờn. Bước 4:
Chọn giỏ trị z0 mới và lặp lại bước 1 cho đến khi đó quột hết tất cả cỏc giỏ trị z0 cần khảo sỏt.
Hỡnh 9.12 Minh hoạ tập Julia 9.6. HỌ CÁC ĐƯỜNG CONG PHOENIX
Họ cỏc đường cong Phoenix do Shigehiro Ushiki ở trường đại học Kyoto tỡm ra. Phương trỡnh của đường cong được xỏc định bởi:
Zn+1 = zn2 + p + q.zn-1 Trong đú:
Zi∈ C ∀i, N. p = (p, 0) ∈C. q = (q, 0) ∈ C.
Phương trỡnh được khai triển thành cỏc phần thực và ảo của zn cú dạng: xn+1 = xn2 – yn2 + p + q.xn-1
yn+1 = 2xn.yn + q.yn-1 với: xn+1 = Re(zn+1); yn+1 = Im(zn+1).
Khi đú việc thể hiện đường cong này lờn màn hỡnh gần giống với việc thể hiện tập Julia. Tuy nhiờn cú hai điểm thay đổi quan trọng:
Thay đổi 1:
Trục x của màn hỡnh biểu thị phần ảo của số phức z0. Trục y của màn hỡnh biểu thị phần thực của số phức z0.
Ởđõy chỳng ta đảo ngược cỏc trục thực và ảo của mặt phẳng phức thụng thường là
để thể hiện hỡnh ảnh theo chiều đứng chứ khụng phải chiều ngang. Hỡnh 14.1 trỡnh bày 1 loại đường cong loại này với yờu cầu rừ ràng là phải đổi vai trũ của trục x và y để hỡnh
ảnh cú thể được thể hiện tốt trờn màn hỡnh. Do đú tương ứng với một điểm ảnh (Col, Row) trờn màn hỡnh sẽ là số phức z = (x, y) cú dạng:
x = ymax – Row * ∆x; y = ymin – Col * ∆y;
Với:
Thay đổi 2:
Thay đổi về thuật toỏn tụ màu. Ởđõy với cỏc điểm thuộc lớp 1 (theo định nghĩa đó nờu ở phần về tập Julia) chỳng ta sẽ sử dụng 3 loại màu tuỳ theo ngưỡng hội tụ:
Màu 1: được sử dụng để tụ cỏc điểm z0 cho ra giỏ trị | zk | < 2 với tối đa k = 32 lần lặp.
Màu 2: được sử dụng để tụ cỏc điểm z0 cho ra giỏ trị | zk | < 2 với số lần lặp từ 33
đến 64.
Màu 3: được sử dụng để tụ cỏc điểm z0 cho ra giỏ trị | zk | < 2 với số lần lặp vượt quỏ 64 lần.
Cũn đối với cỏc điểm thuộc lớp 2, chỳng ta sẽ tụ chỳng bằng một màu khỏc với màu nền hiện tại.
Với cỏc thay đổi như vậy, đoạn mó dựng xỏc định giỏ trị z0 thuộc lớp 1 hay 2, cựng với kỹ thuật tụ màu điểm ảnh sẽđược viết dưới dạng:
for(Col = 0; Col<Max_Col; ++Col) {
for(Row=0; Row<= Max_Row; ++Row){
xn = ymax - Row* ∆x;
yn = xmin + Col* ∆y; X =Y= 0;
Count = 0;
While((Count < Max_Iterations) & (X+Y < 4)){
X = xn2 ; Y = yn2 ; yn+1 = 2xnyn + q yn-1; yn-1 = yn ; xn+1 = X– Y + qxn-1 + p; xn-1 = xn; xn = xn+1; yn = yn+1; ++Count; } if(Count > Max_Iterations)
Tụ màu điểm ảnh (Col, Row) bằng màu dành cho cỏc điểm loại 2;
else
if (Count >= 64)
Tụ màu điểm (Col, Row) bằng màu 3;
else
if (Color >= 32)
Tụ điểm ảnh (Col, Row) bằng màu 2;
else
Tụ điểm ảnh (Col, Row) bằng màu 1;
} } Row Max y y x _ min max− = ∆ Col Max x x y _ min max− = ∆
Đõy là ảnh của đường cong Phoenix
Hỡnh 9.13 Đường cong Phoenix
Bài tập
1. Viết chương trỡnh sinh đường C_curve. 2. Viết chương trỡnh sinh đường Dragons. 3. Viết chương trỡnh sinh đường Kon.
4. Viết chương trỡnh sinh đường Mandelbrot. 5. Viết chương trỡnh sinh đường Pythagoras.
PHỤ LỤC
Hướng dẫn sử dụng thư viện đồ hoạ trong C/C++ hay BC
1. Yờu cầu
Phải cú tập tin điều khiển màn hỡnh EGAVGA.BGI (thụng thường tệp này thường nằm trong thư mục \BC\BGI hay TC\BGI khi cài đặt).
Nếu chỳng ta cú sử dụng tới font chữ thỡ cần phải cú thờm cỏc file (*.CHR) như: GOTH.CHR (chữ Gothic), LITT.CHR (chữ Small Font), SANS.CHR (chữ Sans Serif), TRIP.CHR (chữ cao gấp 3).
Để dựng được thư viện cỏc hàm đồ hoạ cần cú dũng lệnh:
#include <graphics.h> và đặt mục chọn Graphics library là ON ([x] trong menu Options/Linker/Libraries.
Khi cần tham khảo cỳ phỏp, cỏch sử dụng của bất kỳ một hàm đồ hoạ nào, đưa con trỏ về tờn hàm trong chương trỡnh sau đú nhấn tổ hợp phớm CTRL+F1. Muốn tham khảo danh sỏch toàn bộ cỏc hàm của thư viện đồ hoạ nhấn tổ hợp phớm CTRL+F1 ngay tại dũng chữ <graphics.h>.
2. Khởi tạo và đúng chếđộđồ hoạ
Độ phõn giải của màn hỡnh được đo bằng số điểm theo chiều ngang nhõn với số điểm theo chiều dọc của màn hỡnh đồ hoạ. Toạđộ gốc của màn hỡnh đồ hoạ (0,0) là điểm nằm tại gúc trờn cựng phớa bờn trỏi. Mỗi kiểu đồ hoạ dựng một hệ toạđộ riờng. Hệ toạđộ
cho màn hỡnh VGA là 640x480.
Khởi động đồ hoạ với màn hỡnh ngầm định:
#include <graphics.h> void main(void){
int gdriver, gmode, errocode;
gdriver = DETECT;//ngầm định
initgraph(&gdriver,&gmode,”C:\TC\BGI“); //tỡm mode màn hỡnh trong thư mục BGI errorcode = graphresult(); if (errorcode !=grOk) { printf(“\n Khụng khởi tạo được”); getch();exit(1); } ...// Cỏc thao tỏc đồ hoạ tiếp theo closegraph(); }
Vớ dụ: viết chương trỡnh hai đường thẳng cắt nhau
#include <conio.h> #include <graphics.h> #include <math.h>
// hệ số đổi từ độ sang radian #define RADS 0.017453293
void giaodiem(double x1, double y1, double x2, double y2, double a1, double b1, double a2, double b2) {
double dx, dy, da, db, x, y, t, tich; dx = x2 - x1; dy = y2 - y1; da = a2 - a1; db = b2 - b1; tich = db * dx - da * dy; if (tich != 0) {
t = ((a1 - x1) * dy - (b1 - y1) * dx) / tich; if (t>=0.0 && t<=1.0) {
x = t * (a2 - a1) + a1; y = t * (b2 - b1) + b1; line(x1, y1, x2, y2); line(a1, b1, a2, b2); setfillstyle(SOLID_FILL, RED); fillellipse(x, y, 3, 3); } } } void main() {
int gr_drive = DETECT, gr_mode;
double x1, y1, x2, y2, a1, b1, a2, b2;
printf("\nNhap vao toa do doan thang thu nhat: "); scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
printf("\nNhap vao toa do doan thang thu hai: "); scanf("%lf%lf%lf%lf", &a1, &b1, &a2, &b2);
initgraph(&gr_drive, &gr_mode, "");
giaodiem(x1, y1, x2, y2, a1, b1, a2, b2); getch();
closegraph(); //đúng chế độ đồ hoạ
}
3. Cỏc hàm cơ bản
3.1. Bảng màu của màn hỡnh đồ hoạ.
Setbkcolor(int color) thiết lập màu nền cho màn hỡnh đồ hoạ
setcolor(int color) đặt màu vẽ cho nột vẽ hiện tại
getmaxcolor() lấy số màu cao nhất được sử dụng trong chếđộđồ hoạ hiện tại setallpalette(struct palettetype far
*palette)
sẽ làm thay đổi toàn bộ màu trong bảng màu palette
setpalette( int colox, int colory) sẽ làm thay đổi màu thứ colorx thành màu colory getpalette(struct palettetype far
*palette)
sẽ lấy lại giỏ trị của palette đang dựng
textheight(“W”) lấy chiều cao của dũng văn bản
3.2. Điểm
Đơn giản nhất chớnh là điểm, mọi đối tượng khỏc đều được xõy dựng nờn từđiểm. int getmaxx() Số chấm điểm lớn nhất theo chiều ngang trong chếđộđồ hoạ hiện tại int getmaxy() Số chấm điểm lớn nhất theo chiều dọc trong chếđộđồ hoạ hiện tại putpixel( x, y, color) Để vẽ một điểm sỏng lờn màn hỡnh tại điểm (x, y) cú màu color getpixel(x,y) nhận biết màu hiện tại của điểm (x, y)
3.3. Đường
Cỏc hàm cho đường:
moveto(int x, int y) di chuyển vị trớ con trỏ hiện tại của màn hỡnh đồ hoạ tới toạđộ (x,y) getx(), gety() lấy toạđộ của con trỏ hiện tại theo chiều ngang và chiều dọc màn hỡnh đồ
hoạ
lineto(int x, int y) vẽ một đường thẳng từ vị trớ con trỏ hiện tại tới vị trớ cú toạđộ (x, y) trờn màn hỡnh đồ hoạ
line(int x1, int y1, int x2, int y2)
Vẽ một đường thẳng từ toạ độ (x1,y1) đến toạđộ (x2, y2) trờn màn hỡnh
đồ hoạ. Đường thẳng mới được vẽ khụng phụ thuộc vào vị trớ hiện thời của con trỏ màn hỡnh
linerel(int dx, int dy) Vẽ một đoạn thẳng từ vị trớ con trỏ hiện tại tới vị trớ (x +dx, y+dy). Sau khi vẽ con trỏ chuyển tới vị trớ mới (x+dx, y+dy)
3.4. Hỡnh chữ nhật
rectangle(int x1, int y1, int x2, int y2) vẽ hỡnh chữ nhật cú toạđộ phớa gúc trờn bờn trỏi là (x1, y1) và gúc dưới bờn phải cú toạđộ (x2,y2).
bar(int x1, int y1, int x2, int y2) vẽ hỡnh chữ nhật cú tụ màu phớa trong. Hai chỉ thị
rectangle và bar khỏc nhau ở chỗ rectangle chỉ tạo nờn một hỡnh chữ nhật với đường viền bao quanh.
bar3d(int x1,int y1,int x2,int y2,int depth, int top) vẽ khối hộp chữ nhật, mặt ngoài của nú là hỡnh chữ nhật xỏc định bởi cỏc toạđộ (x1,y1,x2,y2) hỡnh chữ nhật này được tụ màu, depth là chiều sõu của khối 3 chiều, top nhận giỏ trị 1 hoặc 0 để khối 3 chiều cú nắp hay khụng cú nắp.
3.5. Hỡnh trũn
Tất cả cỏc hàm dưới đõy, gúc tớnh theo độ và giỏ trị từ 00đến 3600 .
arc(int x, int y, int gd,int gc,int r) vẽ cung trũn cú (x,y) tọa độ tõm trũn, r bỏn kớnh, gd gúc đầu, gc gúc cuối.
circle( int x, int y, int r) là hàm vẽ hỡnh trũn cú tõm tại điểm (x,y) với bỏn kớnh r. ellipse(int x, int y,int gd, int gc,int xr, int yr) vẽ 1 hỡnh ellipse cú (x,y) toạ độ tõm cung, gd gúc đầu, gc gúc cuối, xr là bỏn trục ngang, yr là bỏn trục đứng.
pieslice(int x, int y, int gd, int gc, int r) vẽ và tụ màu hỡnh quạt cú (x,y) là toạđộ tõm quạt, gd là gúc đầu, gc là gúc cuối, r là bỏn kớnh.
3.6. Đa giỏc
drawpoly(int numpoints, int far *polypoints) sẽ vẽ nờn một đường gấp khỳc bất kỳ
với numpoints là số điểm mà đường gấp khỳc đi qua, polypoints (mảng) toạ độ điểm (x1,y1,x2,y2....). Khi điểm cuối (xn,yn) trựng với điểm đầu (x1,y1) thỡ được một đa giỏc.
fillpoly(int numpoints, int *polypoints) sẽ tụ màu đa giỏc bằng màu hiện thời.
setfillstyle(int pattern, int color) dựng để xỏc định mẫu tụ cho đa giỏc, trong đú mẫu tụ là cỏc hằng số nguyờn được định nghĩa như sau:
Tờn hằng mẫu Giỏ trị Mụ tả EMPTY_FILL 0 Tụ bằng màu nền SOLID_FILL 1 Tụ bằng nột liền LINE_FILL 2 Tụ --- LTSLASH_FILL 3 Tụ //// SLASH_FILL 4 Tụ ///// in đậm BKSLASH_FILL 5 Tụ \\\\\ in đậm LTBKSLASH_FILL 6 Tụ \\\\ HATCH_FILL 7 Tụ đường gạch búng nhạt XHATCH_FILL 8 Tụ đường gạch búng chữ thập INTERLEAVE_FILL 9 Tụ đường đứt quóng
WIDE_DOT_FILL 10 Tụ bằng dấu chấm thưa CLOSE_DOT_FILL 11 Tụ bằng dấu chấm dày
3.7. Văn bản
outtext( char far *textstring) sẽ hiển thị nội dung xõu textstring tại vị trớ hiện thời của màn hỡnh đồ hoạ.
outtextxy(int x, int y, char far *textstring) hiển thị nội dung xõu textstring tại toạđộ
(x, y) trong màn hỡnh đồ hoạ.
settextstyle(int font, int direction, int charzise) dựng để xỏc lập kiểu chữ với cỏc font chữ khỏc nhau.
Trong đú int font được xỏc lập thụng qua cỏc hằng sau:
TấN FONT Giỏ trị í nghĩa
DEFAULT_FONT 0 Font 8x8 bit-mapped
TRIPLEX_FONT 1 Stroked triplex font
SMALL_FONT 2 Stroked small font
SANS_SERIF_FONT 3 Stroked sans-serif font
int direction được xỏc định nếu HORIZ_DIR = 0 là nằm ngang từ trỏi qua phải, VERT_DIR =1 là thẳng đứng từ dưới lờn trờn.
int charsize nhận giỏ trị từ 1 đến 10 là hệ số phúng đại chữ.
settextjustification( int hoz, int vert) xỏc định vị trớ dũng văn bản được đưa ra màn hỡnh đồ hoạ bởi outtext() và outtextxy().
Trong đú int hoz cú thể nhận một trong cỏc hằng sau:
LEFT_TEXT =0 văn bản xuất hiện phớa bờn trỏi con trỏ màn hỡnh đồ hoạ
CENTER_TEXT =1 văn bản xuất hiện ở giữa với tõm là con trỏ màn hỡnh đồ
hoạ
RIGHT_TEXT =2 văn bản xuất hiện phớa bờn phải con trỏ màn hỡnh đồ hoạ
Cũn int vert là tham số cú thể nhận cỏc giỏ trị sau:
BOOTTOM_TEXT=0 văn bản xuất hiện ở phớa trờn con trỏ
CENTER_TEXT=1 văn bản xuất hiện ở quanh con trỏ
TOP_TEXT=2 văn bản xuất hiện ở phớa dưới con trỏ