
TH- ðỒ HỌA MÁY TÍNH 1 GVHD: Huynh Duc Nghia
CÁC THUẬT TOÁN VẼ ðƯỜNG
Bài 1 :
Mục tiêu :
Bài thực hành cho biết cách dùng
hàm InitGraph khởi tạo chế ñộ ñồ họa
hàm closegraph
ngưng làm việc trên chế dộ ñồ họa
hàm putpixel(x,y,color) vẽ một ñiểm ảnh tại vị trí x, y với màu color
hàm getpixel(x,y) trả về giá trị màu sắc tại vị trí x, y
Xây dựng hàm khởi tạo chế ñộ ñồ họa
#include <graphics.h>
void InitGraph()
{
int gd=DETECT,gm; //Khai báo 2 biến gd và gm kiểu số nguyên
initgraph(&gd,&gm,"C:\\NGHIA\\THUCHANH\\DOHOA\\TC\\BGI"); // Goi hàm khởi tạo ñồ
họa
}
Cấu trúc một chương trình ñồ họa thông thường
void main ()
{
Inputdata(); // Nhập dữ liệu cho chương trình – Tọa ñộ của một ñiểm, bán kính
InitGraph(); // Khoi tao che do do hoa
Draw(); // Các thao tác ñồ họa
closegraph(); // Ngừng chế ñộ làm việc của ñồ họa
}
* Chương trình vẽ bầu trời sao nhấp nháy minh họa các hàm vừa nêu trên
#include <graphics.h>
#include <stdlib.h>
#include <conio.h>
viod DrawSky()
{
int x,y,color;
randomize(); //khoi tao random (stdlib.h)
while(!kbhit()) // int kbhit() = 0 Neu bo dem ban phim rong (conio.h)
{
x = random(640); y = random(480);
color = random(16);
if(getpixel(x,y) != color) //Lay gia tiị mau tai vi tri x,y so sanh voi mau se ve
putpixel(x,y,color); // Ve mau khac neu khong phai la mau da ve
else putpixel(x,y,1); //Ve lai gia tri mau nen BLACK
}
}
void main()
{
InitGraph();
DrawSky();
closegraph()

TH- ðỒ HỌA MÁY TÍNH 2 GVHD: Huynh Duc Nghia
}
Bài 2: Viết hàm main() vẽ hình chữ nhật và hình tròn
Gợi ý : Dùng hàm line() hoặc rectangle() và circle() do chương trình C cung cấp.
ðường thẳng, hình vuông, hình tròn ñược vẽ như thế nào?
Bài 3: Cài ñặt giải thuật vẽ ñường thẳng bằng thuật toán thô, vẽ ñường thẳng có các tọa ñộ x1 = 150, y1 =
150, x2 = 250, y2 = 200 và màu tùy ý.
Gợi ý: tạo hàm DT(x1,y1,x2,y2,Color)
- Vẽ ñiểm ñầu tiên (x1,y1)
- Tính hệ số góc m và hệ số b
- ðiểm tiếp theo cho ñến ñiểm (x2,y2) , dùng:
for (int x=x1; x<x2; x++)
{ y=m*x+b;
putpixel(x,Round(y),Color);
}
Chương trình minh hoa
#include <graphics.h>
#include <stdlib.h>
#include <conio.h>
#define Round(a) int(a+0.5)
void Line(int x1, int y1, int x2, int y2)
{
putpixel(x1,y1,RED);
float m=(float)(y2-y1)/(x2-x1);
float b=y1-m*x1;
int y;
for (int x=x1; x<x2; x++)
{ y=m*x+b;
putpixel(x,Round(y),RED);
}
}
void InitGraph()
{
int gd=DETECT,gm;
initgraph(&gd,&gm,"C: \\NGHIA\\THUCHANH\\DOHOA\\TC\\BGI");
}
void main()
{
InitGraph();
Line(150,150,250,200);
getch();
closegraph();
}
Câu hỏi: Trường hợp giải thuật trên áp dụng cho m thuộc khoảng miền giá nào?
Hãy dùng giải thuật trên vẽ hình vuông , chữ nhật, tam giác, tứ giác, da giác lồi, lõm.
Bài 4: Cài ñặt thuật toán DDA, vẽ ñường thẳng như bài 3
Giải thuật: (với 0<m<1)

TH- ðỒ HỌA MÁY TÍNH 3 GVHD: Huynh Duc Nghia
#define Round(a) int(a+0.5) //ðịnh nghĩa hàm làm tròn số a nguyên
void LineDDA (int x1, int y1, int x2, int y2, int Color)
{
int x = x1;
float y = y1;
float m = float(y2-y1)/(x2-x1);
putpixel(x, Round(y), Color);
for(int i=x1; i<x2; i++)
{
x++;
y +=m;
putpixel(x, Round(y), Color);
}
} // LineDDA
Yêu cầu:
- Hãy dùng giải thuật trên vẽ hình vuông , chữ nhật, tam giác, tứ giác, da giác lồi, lõm.
- Cài ñặt thuật toán DDA với m>1, vẽ ñường thẳng, có các tọa ñộ x1 = 100, y1 = 100, x2 = 200, y2
= 300 và màu tùy ý (ðối xứng TH với 0<m<1)
Bài 5: Cài ñặt thuật toán Bresenham, Dùng thuật toán Bresenham vẽ ñường thẳng như bài 3
Giải thuật: (với 0<m<1)
void LineBres1 (int x1, int y1, int x2, int y2, int Color)
{
int Dx, Dy, p, twoDy, twoDyDx, Const2;
int x, y;
Dx = x2 - x1;
Dy = y2 - y1;
twoDy = 2*Dy; // Dy <<1
twoDyDx = 2*(Dy-Dx); // (Dy-Dx) <<1
p = twoDy - Dx; // Dy <<1 - Dx
putpixel(x, y, Color);
for(x=x1; x<x2; x++)
{
if (p<0)
p += twoDy;
else
{
p += twoDyDx;
y++;
}
putpixel(x, y, Color);
}
} // LineBres1
Yêu cầu:
- Hãy dùng giải thuật trên vẽ hình vuông , chữ nhật, tam giác, tứ giác, da giác lồi, lõm.
- Cài ñặt thuật toán Bresenham ñể vẽ ñường thẳng có hệ số góc tùy ý (LineBresX) ñược mô tả như sau:
Void LineBresX(x1,y1,x2,y2,Color)
{
*Nếu x1!=x2, thì:
Tính hệ số góc m.

TH- ðỒ HỌA MÁY TÍNH 4 GVHD: Huynh Duc Nghia
Nếu 0<m<1 => gọi hàm LineBres1();
Nếu m>1 => gọi hàm LineBres2();
Nếu -1<m<0 => gọi hàm LineBres3();
Nếu m<-1 => gọi hàm LineBres4();
*Ngược lại gọi hàm LineBresV(); //Vẽ ñường thẳng ñứng
}
Bài 6: Cài ñặt thuật toán vẽ ñường tròn MidPoint
// Ve 8 diem doi xung
void Put8Pixel(int x, int y, int Color)
{
putpixel(x, y, Color);
putpixel(y, x, Color);
putpixel(y, -x, Color);
putpixel(x, -y, Color);
putpixel(-x, -y, Color);
putpixel(-y, -x, Color);
putpixel(-y, x, Color);
putpixel(-x, y, Color);
} // Put8Pixel
void CircleMidPoint (int R)
{
int x, y;
x = 0;
y = R;
Put8Pixel(x, y,WHITE);
int p = 1 - R; //Tại sao ở ñây có số 1?
while (x < y)
{
if (p < 0)
p += 2*x + 3;
else
{
p += 2*(x -y) + 5;
y--;
}
x++;
Put8Pixel(x, y,WHITE);
}
} // CircleMidPoint
Yêu cầu:
- Hãy dùng giải thuật trên vẽ ñường tròn.
- Vẽ ñường tròn tâm x
c
,y
c
bất kỳ
Bài 7: Cài ñặt thuật toán vẽ ñường tròn Bresenham
void CircleBres (int R)
{
int x, y;
x = 0;
y = R;
Put8Pixel(x, y,WHITE);

TH- ðỒ HỌA MÁY TÍNH 5 GVHD: Huynh Duc Nghia
p = 3 – 2*R;
while (x < y)
{
x++;
if (p < 0)
p += 4*x + 6;
else
{ y--;
p += 4*(x -y) + 10;
}
Put8Pixel(x, y,WHITE);
}
} // CircleBres
Yêu cầu: - Dùng giải thuật trên vẽ ñường tròn.
- Vẽ ñường tròn tâm x
c
,y
c
bất kỳ.
Tự cài ñặt chương trình: vẽ ellipse, parabol, và một số ñường cong khác,…
CÁC THUẬT TOÁN TÔ MÀU
Tô màu dựa theo ñường biên
Bài 1 : Cài ñặt giải thuật tô màu với lân cận 4.
Cài ñặt giải thuật:
void FloodFill4(int x, int y, int bc, int nc) //bc: back color, nc: new color
{
int color= getpixel(x,y);
if ((color != bc) && (color != nc))
{
putpixel(x,y,nc);
delay(30);
FloodFill4(x-1,y,bc,nc);
FloodFill4(x+1,y,bc,nc);
FloodFill4(x,y-1,bc,nc);
FloodFill4(x,y+1,bc,nc);
}
}
Chương tình minh họa
#include <graphics.h>
#include <stdlib.h>
#include <conio.h>
#include <stdio.h>
#include <dos.h>
#define Round(a) int(a+0.5)
int Color = WHITE;
void FloodFill4(int x, int y, int bc, int nc)
{
int color= getpixel(x,y);
if ((color != bc) && (color != nc))
{