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
Phụ
lục 1
143
#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
Phụ
lục 1
144
outextxy(int x, int y, char * msg) Chỉ thị đưa
xâu kí tự msg ra màn hình đồ hoạ tại
vị trí (x,y)
3.2. Nguyên sơ điểm
Nguyên sơ
đơn giản nhất
chính là điểm, mọi nguyên sơ
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. Nguyên sơ đườ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. Nguyên sơ 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. Nguyên sơ 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.
Phụ
lục 1
145
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. Nguyên sơ đ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. Nguyên sơ 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
Phụ
lục 1
146
SMALL_FONT 2 Stroked small font
SANS_SERIF_FONT 3 Stroked sans-serif font
GOTHIC_FONT 4 Stroked gothic 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ỏ
textheight(char *s) trả về chiều cao (theo pixel) của chuỗi
do s trỏ tới. Với
8x8 bit map Font
và hệ
số khuyếch đại chữ
là 1 thì textheight(“H”)=8
textwidth(char *s) trả về chiều dài của
chuỗi tính theo pixel.
3.8. Cửa sổ (viewport)
viewport là 1 vùng hình chữ nhật
trên màn hình đồ hoạ giống như
window trong textmode.
setviewport(int x1, int y1, int x2, int y2, int clip) trong
đó (x1,y1,x2,y2) là góc trái trên và
góc phải
dưới thoả mãn điều kiện
như sau:
0<=x1 <= x2 và 0<= y1 <= y2
Tham số
clip: clip=1 không cho phép vẽ
ra ngoài viewport
clip=0 cho phép vẽ
ra ngoài viewport
getviewsettings(struct
viewporttype *vp) nhận viewport hiện hành,
struct viewporttype {
int
left,top,right,bottom;
int clip;
};
clearviewport(void) xoá viewport
cleardevice(void) xoá mọi thứ
trên màn hình và đưa con trỏ về toạ độ
(0,0) của màn hình
Chú ý: nhờ
sử dụng viewport ta có thể viết các chương
trình đồ hoạ có trục
toạ độ, bằng
cách thiết lập
viewport với clip=0 (cho phép vẽ ra ngoài giới hạn)
3.9. Tạo hình ảnh chuyển động
Nguyên sơ
mới mà chúng ta sẽ xây dựng
là tạo hình ảnh chuyển
động trên màn hình đồ hoạ.
Về nguyên tắc,
để có thể tạo
nên những hình ảnh chuyển
động chúng ta cần có một
hình mẫu, sau
Phụ
lục 1
147
đó lưu
hình mẫu trên màn hình đồ hoạ lại
bằng chỉ thị
getimage(int x1, int y1, int x2, int y2, void
far *bitmap); trong đó bitmap là miền nhớ dùng để
lưu hình ảnh của
hình chữ nhật có toạ
độ
(x1,y1) và (x2, y2) trên màn hình đồ hoạ.
Chỉ
thị getimagesize(int x1, int y1, int x2,
int y2) dùng để xác định kích thước
bộ nhớ dùng
để cất hình ảnh giới
hạn trong hình chữ nhật
có toạ độ (x1, y1), (x2,y2).
Chỉ
thị putimage(int x, int y, void far *
bitmap, int copymode) dùng để
khôi phục lại hình
ảnh đã được
cất giữ bằng
getimage(). Chỉ thị putimage() kết hợp
với chỉ thị
làm trễ (delay() ) sao
cho số
các hình ảnh hiển thị
trên màn hình đồ hoạ khoảng 24 hình/giây chúng ta sẽ nhận
được một
hình ảnh
chuyển động.
Ví dụ 1: Tạo
hình ảnh chuyển động
là một mũi tên.
#include
<graphics.h>
#include
<stdlib.h>
#include
<stdio.h>
#include
<conio.h>
#define ARROW_SIZE 10
void draw_arrow(int
x, int y);
int main(void) {
/* request
autodetection */
int gdriver = DETECT,
gmode, errorcode;
void *arrow;
int x, y, maxx;
unsigned int size;
/* initialize
graphics and local variables */
initgraph(&gdriver,
&gmode, "\\TC\\BGI");
/* read result of
initialization */
errorcode =
graphresult();
if (errorcode !=
grOk) { /* an error occurred */
printf("Graphics
error: %s\n", grapherrormsg(errorcode));
printf("Press
any key to halt:");
getch();
exit(1); /* terminate
with an error code */
}
maxx = getmaxx(); x =
0;
y = getmaxy() / 2;
/* draw the image to
be grabbed */
draw_arrow(x, y);
/* calculate the size
of the image */
size = imagesize(x,
y-ARROW_SIZE, x+(4*ARROW_SIZE), y+ARROW_SIZE);
/* allocate memory to
hold the image */
arrow = malloc(size);
/* grab the image */
getimage(x, y-ARROW_SIZE,
x+(4*ARROW_SIZE), y+ARROW_SIZE, arrow);
/* repeat until a key
is pressed */
Phụ
lục 1
148
while (!kbhit()){
/* erase old image */
putimage(x,
y-ARROW_SIZE, arrow, XOR_PUT);
x += ARROW_SIZE;
if (x >= maxx)
x = 0;
/* plot new image */
putimage(x,
y-ARROW_SIZE, arrow, XOR_PUT);
}
/* clean up */
free(arrow);
closegraph();
return 0;
}
void draw_arrow(int
x, int y) {
/* draw an arrow on
the screen */
moveto(x, y);
linerel(4*ARROW_SIZE,
0);
linerel(-2*ARROW_SIZE,
-1*ARROW_SIZE);
linerel(0,
2*ARROW_SIZE);
linerel(2*ARROW_SIZE,
-1*ARROW_SIZE);
}
Các code chương trình ví dụ cho
bài tập lập trình
Bài 1: quay đối tượng
#include<stdio.h>
#include<dos.h>
#include<conio.h>
#include<graphics.h>
#include<stdlib.h>
#include<math.h>
#include<alloc.h>
#define RADS
0.017453293
struct point{
int x,y,z;
}
a[4]=
{
{110,180,80},
{10,200,80},
{120,50,80},
{110,180,250}
};
int noi[4][4];
void
Bresenham_Line(int x1,int y1, int x2, int y2, int c)
{
Phụ
lục 1
149
if(x1 == x2)
{
int i;
if(y1 < y2)
for(i = y1; i <=
y2;i ++)
{
putpixel(x1,i,c);
delay(10);
}
else
for(i = y2; i<=
y1; i ++)
{
putpixel(x1,i,c);
delay(10);
}
}
if(y1 == y2)
{
int i;
if(x1 < x2)
for(i = x1; i <=
x2; i ++)
{
putpixel(i,y1,c);delay(10);
}
else
for(i = x2; i <=
x1; i ++)
{
putpixel(i,y1,c);
delay(10);
}
}
if(x1 < x2)
{
if(y1 < y2)
{
if((y2 - y1)/(x2-x1)
< 1)
{
int i;
int Dx = x2 - x1;
int Dy = y2 - y1;
int p = 2*Dy - Dx;
putpixel(x1,y1,c);
for(i = x1; i <
x2; i ++)
{
if(p < 0)
p += 2*Dy;
else
{
p += 2*(Dy - Dx);
y1 ++;
}
x1 ++;
putpixel(x1,y1,c);
delay(10);
Phụ
lụ__________c 1
150
}
}
else
{
int i;
int Dx = x2 - x1;
int Dy = y2 - y1;
int p = 2*Dx - Dy;
putpixel(x1,y1,c);
for(i = y1; i <
y2; i ++)
{
if(p < 0)
p += 2*Dx;
else
{
p += 2*(Dx - Dy);
x1 ++;
}
y1 ++;
putpixel(x1,y1,c);
delay(10);
}
}
}
if(y1 > y2)
{ if((y2 - y1)/(x2 -
x1)> -1 )
{
int i;
int Dx = x2 - x1;
int Dy = y2 - y1;
int p = 2*Dy + Dx;
putpixel(x1,y1,c);
for(i = x1; i <=
x2; i ++)
{
if(p > 0)
p += 2*Dy;
else
{
p += 2*(Dy + Dx);
y1-- ;
}
x1 ++;
putpixel(x1,y1,c);
delay(10);
}
}
else
{
int i;
int Dx = x2 - x1;
int Dy = y2 - y1;
int p = 2*Dx + Dy;
Phụ
lục 1
151
putpixel(x1,y1,c);
for(i = y1; i >=
y2; i --)
{
if(p < 0)
p += 2*Dx;
else
{
p += 2*(Dx + Dy);
x1++ ;
}
y1 --;
putpixel(x1,y1,c);
delay(10);
}
}
}
}
if(x1 > x2)
{
if(y1 < y2)
{ if((y2-y1)/(x2-x1)
> -1)
{
int i;
int Dx = x2 - x1;
int Dy = y2 - y1;
int p = -2*Dy - Dx;
putpixel(x1,y1,c);
for(i = x1; i >
x2; i --)
{
if(p < 0)
{
p=p - 2*Dy - 2*Dx;
y1 ++;
}
else
p =p - 2*Dy;
x1 --;
putpixel(x1,y1,c);delay(10);
}
}
else
{
int i;
int Dx = x2 - x1;
int Dy = y2 - y1;
int p = -2*Dx - Dy;
putpixel(x1,y1,c);
for(i = y1; i <
y2; i ++)
{
if(p < 0)
p -= 2*Dx;
Phụ
lục 1
152
else
{
p -= 2*(Dx + Dy);
x1 --;
}
y1 ++;
putpixel(x1,y1,c);
delay(10);
}
}
}
if(y1 > y2)
{
if((y2-y1)/(x2-x1)
< 1)
{
int i;
int Dx = x2 - x1;
int Dy = y2 - y1;
int p = 2*Dy - Dx;
putpixel(x1,y1,c);
for(i = x1; i >
x2; i --)
{
if(p > 0)
{
p =p - 2*Dy +2*Dx ;
y1--;
}
else
p -= 2*Dy;
x1 --;
putpixel(x1,y1,c);
delay(10);
}
}
else
{
int i;
int Dx = x1 - x2;
int Dy = y1 - y2;
int p = 2*Dx + Dy;
putpixel(x1,y1,c);
for(i = y1; i >
y2; i --)
{
if(p < 0)
{
p =p - 2*Dx + 2*Dy ;
x1 --;
}
else
Phụ
lục 1
153
p =p - 2*Dx ;
y1 --;
putpixel(x1,y1,c);
delay(10);
}
}
}
}
}
void Dothi()
{
Bresenham_Line(getmaxx()/2,getmaxy()/2,getmaxx()-10,getmaxy()/2,15);
Bresenham_Line(getmaxx()/2,10,getmaxx()/2,getmaxy()/2,15);
Bresenham_Line(getmaxx()/2,getmaxy()/2,getmaxx()/2-170,getmaxy()/2+170,15);
Bresenham_Line(getmaxx()/2-170,getmaxy()/2+170,getmaxx()/2-170,getmaxy()/2+166,15);
Bresenham_Line(getmaxx()/2-170,getmaxy()/2+170,getmaxx()/2-163,getmaxy()/2+167,15);
settextjustify(CENTER_TEXT,CENTER_TEXT);
outtextxy(getmaxx()-9,getmaxy()/2+1,"_");
outtextxy(getmaxx()-9,getmaxy()/2+10,"y");
outtextxy(getmaxx()/2,10,"-");
outtextxy(getmaxx()/2
- 10,10,"z");
outtextxy(getmaxx()/2-155,getmaxy()/2+170,"x");
}
point Diem3d(int x ,
int y , int z)
{
point p;
if(x>=0&&y>=0&&z>=0)
{
p.x =
int(getmaxx()/2+y - x*cos(RADS*45));
p.y =
int(getmaxy()/2-z + x*cos(RADS*45));
}
if(y>=0&&x<0&&z>=0)
{
p.x =
int(y+getmaxx()/2-x*cos(RADS*45));
p.y =
int(getmaxy()/2-z+x*cos(RADS*45));
}
if(x>=0&&y<0&&z>=0)
{
p.x =
int(getmaxx()/2+y-x*cos(RADS*45));
p.y =
int(getmaxy()/2-(z-x*cos(RADS*45)));
}
if(x>=0&&y>=0&&z<0)
{
p.x =
int(getmaxx()/2+y-x*cos(RADS*45));
p.y =
getmaxy()/2-z+x*cos(RADS*45);
}
if(y>=0&&x<0&&z<0)
{
p.x =
int(getmaxx()/2+y-x*cos(RADS*45));
p.y =
int(getmaxy()/2+(-z-x*cos(RADS*45)));
Phụ
lục 1
154
}
if(x>=0&&y<0&&z<0)
{
p.x =
int(getmaxx()/2+y-x*cos(RADS*45));
p.y =
int(getmaxy()/2-z+x*cos(RADS*45));
}
if(z>=0&&y<0&&x<0)
{
p.x =
int(getmaxx()/2-(-y+x*cos(RADS*45)));
p.y =
int(getmaxy()/2-(z-x*cos(RADS*45)));
}
if(x<0&&y<0&&z<0)
{
p.x =
int(getmaxx()/2+y-x*cos(RADS*45));
p.y =
int(getmaxy()/2-z+x*cos(RADS*45));
}
return(p);
}
point hinhchieu(int
&x, int &y , int &z , int chieu)
{
point p;
if(chieu==1)
{
p.x =int(
getmaxx()/2+y - x*cos(RADS*45));
p.y =int( getmaxy()/2
+ x*cos(RADS*45));
}
if(chieu==2)
{
p.x =int (
getmaxx()/2+y-x*cos(RADS*45)-y);
p.y =int (
getmaxy()/2-z+x*cos(RADS*45));
}
if(chieu == 3)
{
p.x =int(
getmaxx()/2+y-x*cos(RADS*45)+x*sin(RADS*45));
p.y =int(
getmaxy()/2-z);
}
return(p);
}
point quay(int
&x, int &y, int &z, int goc , int chieu)
{
point p;
if(chieu==1)
{
p.x = x*cos(RADS*goc)
+ z*sin(RADS*goc);
p.z =
-x*sin(RADS*goc) + z * cos(RADS*goc);
p.y = y;
}
if(chieu==2)
{
p.y = y*cos(RADS*goc)
- z*sin(RADS*goc);
Phụ
lục 1
155
p.z = y*sin(RADS*goc)
+ z * cos(RADS*goc);
p.x =x;
}
if(chieu==3)
{
p.x =
x*cos(RADS*goc)-y*sin(RADS*goc);
p.y =
x*sin(RADS*goc)+y*cos(RADS*goc);
p.z = z;
}
return p;
}
void chieumat(point
k[],int t, int m )
{
int i,j=0;
int n[4][4];
for(i = 0 ; i<4 ;
i++)
for(j = 0 ; j<4 ;
j++)
{
n[i][j]=1;
n[j][i]=1;
}
for(i = 0 ; i< 4 ;
i++)
{
k[i] =
hinhchieu(k[i].x,k[i].y,k[i].z,t);
}
for( i = 0 ; i< 4
; i++)
for( j = 0 ; j< 4
; j++)
{
if(i!=j&&n[i][j]==1&&n[j][i]==1)
{
Bresenham_Line(k[i].x,k[i].y,k[j].x,k[j].y,m);
n[i][j]=0;
n[j][i]=0;
}
}
}
void main()
{
clrscr();
point b[4],c[4],l[4];
int j=0;
int goc[2]={45,35};
int driver = DETECT,
mode;
initgraph(&driver,&mode,"c:\\tc\\bgi");
Dothi();
for(int i = 0; i <
4; i ++)
b[i] =
Diem3d(a[i].x,a[i].y,a[i].z);
for( i = 1; i < 4;
i ++ )
{
Bresenham_Line(b[j].x,b[j].y,b[i].x,b[i].y,10);
Phụ
lục 1
156
}
Bresenham_Line(b[1].x,b[1].y,b[2].x,b[2].y,10);
Bresenham_Line(b[1].x,b[1].y,b[3].x,b[3].y,10);
Bresenham_Line(b[2].x,b[2].y,b[3].x,b[3].y,10);
settextjustify(LEFT_TEXT,RIGHT_TEXT);
printf("\nQuay
quanh truc : oy goc 45");
printf("\nQuay
quanh truc : ox goc 35.5");
for( i = 0 ; i< 4
; i++)
{
c[i] = quay(a[i].x ,
a[i].y , a[i].z , goc[1] ,1);
}
for(i = 0 ; i< 4 ;
i++)
{
c[i] =
quay(c[i].x,c[i].y,c[i].z,goc[2],2);
}
for(i = 0; i< 4; i
++)
l[i] = c[i];
for( i = 0; i < 4;
i ++)
c[i] =
Diem3d(c[i].x,c[i].y,c[i].z);
outtextxy(10,110,"Chon
mat chieu: ");
outtextxy(10,120,"xoy:
Bam so 1.");
outtextxy(10,130,"xoz:
Bam so 2.");
outtextxy(10,140,"yoz:
Bam so 3.");
outtextxy(10,150,"Bam
so 4 de ket thuc");
char m;
do{
m = getch();
for(i = 0;i < 4; i
++)
c[i] = l[i];
switch (m)
{
case '1' :{
chieumat(c,1,5);
break;
}
case '2' :{
chieumat(c,2,7);
break;
}
case '3' :
{
chieumat(c,3,9) ;
break;
}
}
}while( m !='4');
closegraph();
}
Bài 2: xén tỉa
#include
<conio.h>
Phụ
lục 1
157
#include
<graphics.h>
#include
<math.h>
#include
<stdlib.h>
#define ROUND(a)
((double)(a+0.5)
#define TRUE 1
#define FALSE 0
int cliptest(double
p, double q, double *u1, double *u2)
{
double r;
int retVal = TRUE;
if (p < 0.0)
{
r = q / p;
if (r > *u2)
retVal = FALSE;
else
if (r > *u1)
*u1 = r;
}
else
if ( p > 0.0)
{
r = q / p;
if (r < *u1)
retVal = FALSE;
else
if (r < *u2)
*u2 = r;
}
else
{
if (q < 0.0)
retVal = FALSE;
}
return (retVal);
}
void clipline(double
x1, double y1, double x2, double y2,
double xmin, double
ymin, double xmax, double ymax)
{
double u1 = 0.0, u2 =
1.0, dx, dy;
double oldx1, oldy1,
oldx2, oldy2;
oldx1 = x1;
oldy1 = y1;
oldx2 = x2;
oldy2 = y2;
dx = x2 - x1;
if (cliptest(-dx, x1
- xmin, &u1, &u2))
if (cliptest(dx,
xmax-x1, &u1, &u2))
{
dy = y2 - y1;
Phụ
lục 1
158
if (cliptest(-dy, y1
- ymin, &u1, &u2))
if (cliptest(dy, ymax
- y1, &u1, &u2))
{
if (u2 < 1.0)
{
x2 = x1 + u2 * dx;
y2 = y1 + u2 * dy;
}
if (u1 > 0.0)
{
x1 += u1 * dx;
y1 += u1 * dy;
}
setcolor(RED);
line(oldx1, oldy1,
x1, y1);
line(x2, y2, oldx2,
oldy2);
setcolor(YELLOW);
line(x1, y1, x2, y2);
}
}
}
void main()
{
int gr_drive =
DETECT, gr_mode;
char c;
double x1, y1, x2,
y2;
initgraph(&gr_drive,
&gr_mode, "");
rectangle(100,50,
getmaxx()-100, getmaxy()-50);
randomize();
outtextxy(100,
getmaxy()-10, "Nhan phim bat ky de sinh duong khac; ESC de thoat");
do {
x1 = random(getmaxx()
/ 2);
y1 =
random(getmaxy());
x2 = getmaxx()/2 +
random(getmaxx() / 2);
y2 =
random(getmaxy());
clipline(x1, y1, x2,
y2, 100, 50, getmaxx()-100, getmaxy()-50);
c = getch();
} while (c != 27);
closegraph();
}
Bài 3: Phép chiếu
#include<stdio.h>
#include<dos.h>
#include<conio.h>
#include<graphics.h>
#include<stdlib.h>
#include<math.h>
#include<alloc.h>
#define RADS
0.017453293
struct point{
Phụ
lục 1
159
int x,y,z;
}
a[8]=
{
{30,100,50},
{30,230,50},
{30,230,90},
{30,100,90},
{120,100,50},
{120,230,50},
{120,230,90},
{120,100,90}
};
int n = 3,*d;
int noi[20][20];
void Dothi()
{
line
(getmaxx()/2,getmaxy()/2,getmaxx()-10,getmaxy()/2);
line
(getmaxx()/2,10,getmaxx()/2,getmaxy()/2);
line
(getmaxx()/2,getmaxy()/2,getmaxx()/2-170,getmaxy()/2+170);
line
(getmaxx()/2-170,getmaxy()/2+170,getmaxx()/2-170,getmaxy()/2+166);
line
(getmaxx()/2-170,getmaxy()/2+170,getmaxx()/2-163,getmaxy()/2+167);
settextjustify(CENTER_TEXT,CENTER_TEXT);
outtextxy(getmaxx()-9,getmaxy()/2+1,"0");
outtextxy(getmaxx()-9,getmaxy()/2+10,"y");
outtextxy(getmaxx()/2,10,"-");
outtextxy(getmaxx()/2
- 10,10,"z");
outtextxy(getmaxx()/2-155,getmaxy()/2+170,"x");
}
point Diem3d(int
&x, int &y, int &z)
{
point p;
p.x =
int(getmaxx()/2+ y - x*cos(RADS*45));
p.y = int(getmaxy()/2
- z + x*cos(RADS*45));
return p;
}
point chance(int
&x , int &y , int &z)
{
point p;
if(x>=0&&y>=0&&z>=0)
{
p.x = getmaxx()/2+y -
x*cos(RADS*45);
p.y = getmaxy()/2-z +
x*cos(RADS*45);
}
if(y>=0&&x<0&&z>=0)
{
p.x =
y+getmaxx()/2-x*cos(RADS*45);
p.y =
getmaxy()/2+z-x*cos(RADS*45);
}
Phụ
lục 1
160
if(x>=0&&y<0&&z>=0)
{
p.x =
getmaxx()/2+y-x*cos(RADS*45);
p.y =
getmaxy()/2-(z-x*cos(RADS*45));
}
if(x>=0&&y>=0&&z<0)
{
p.x =
getmaxx()/2+(sqrt(pow(x,2)+pow(y,2)))*cos(RADS*45);
p.y =
getmaxy()/2+(sqrt(pow(x,2)+pow(y,2)))*cos(RADS*45)-z;
}
if(y>=0&&x<0&&z<0)
{
p.x =
getmaxx()/2+y-x*cos(RADS*45);
p.y =
getmaxy()/2+(-z-x*cos(RADS*45));
}
return(p);
}
point hinhchieu(int
&x, int &y , int &z , int chieu)
{
point p;
if(chieu==1)
{
p.x =int(
getmaxx()/2+y - x*cos(RADS*45));
p.y =int(
getmaxy()/2+x*cos(RADS*45));
}
if(chieu==2)
{
p.x =int (
getmaxx()/2+y-x*cos(RADS*45)-y);
p.y =int (
getmaxy()/2-z+x*cos(RADS*45));
}
if(chieu == 3)
{
p.x =int(
getmaxx()/2+y-x*cos(RADS*45)+x*sin(RADS*45));
p.y =int(
getmaxy()/2-z);
}
return(p);
}
point quay(int
&x, int &y, int &z, int goc , int chieu)
{
point p;
if(chieu==1)
{
p.x = x*cos(RADS*goc)
+ z*sin(RADS*goc);
p.z =
-x*sin(RADS*goc) + z * cos(RADS*goc);
p.y = y;
}
if(chieu==2)
{
p.y = y*cos(RADS*goc)
- z*sin(RADS*goc);
p.z = y*sin(RADS*goc)
+ z * cos(RADS*goc);
Phụ
lục 1
161
p.x =x;
}
if(chieu==3)
{
p.x =
x*cos(RADS*goc)-y*sin(RADS*goc);
p.y =
x*sin(RADS*goc)+y*cos(RADS*goc);
p.z = z;
}
return p;
}
void chieumat(point
k[],int t, int &m )
{
int i,j;
for(i = 0 ; i< 8 ;
i++)
k[i] =
hinhchieu(k[i].x,k[i].y,k[i].z,t);
for( i = 0 ; i< 8
; i++)
for( j = 0 ; j< 8
; j++)
{
if(noi[i][j]==1&&noi[j][i]==1)
{
Bresenham_Line(k[i].x,k[i].y,k[j].x,k[j].y,m);
}
}
noi[0][3]=1,noi[3][0]=1;
noi[4][7]=1,noi[7][4]=1;
noi[3][7]=1,noi[7][3]=1;
}
void main()
{
clrscr();
d = &n;
point
b[8],g[3][8],c[8],l[8];
int t, goc ;
int driver = DETECT,
mode;
initgraph(&driver,&mode,"c:\\tc\\bgi");
Dothi();
for(int i = 0; i <
8; i ++)
b[i] =
Diem3d(a[i].x,a[i].y,a[i].z);
for( i = 0; i < 3;
i ++ )
{
line(b[i].x,b[i].y,b[i
+ 4].x,b[i + 4].y);
line(b[i].x,b[i].y,b[i+1].x,b[i+1].y);
line(b[i+4].x,b[i+4].y,b[i+5].x,b[i+5].y);
noi[i][i+4]=1 ,
noi[i+4][i] =1;
noi[i][i+1] = 1,
noi[i+1][i]=1;
noi[i+4][i+5]=1,
noi[i+5][i+4]=1;
}
noi[0][3]=1,noi[3][0]=1;
noi[4][7]=1,noi[7][4]=1;
noi[3][7]=1,noi[7][3]=1;
Phụ
lục 1
162
line(b[0].x,b[0].y,b[3].x,b[3].y);
line(b[4].x,b[4].y,b[7].x,b[7].y);
line(b[3].x,b[3].y,b[7].x,b[7].y);
settextjustify(LEFT_TEXT,RIGHT_TEXT);
printf("\nQuay
quanh truc :");
printf("\ny.Bam
so 1");
printf("\nx.Bam
so 2.");
printf("\nz.Bam
so 3.");
scanf("%d",&t);
printf("\nQuay
goc bao nhieu do:");
scanf("%d",&goc);
for( i = 0 ; i<= 7
; i++)
{
c[i] = quay(a[i].x ,
a[i].y , a[i].z , goc ,t);
l[i] = c[i];
}
for( i = 0; i < 8;
i ++)
c[i] =
Diem3d(c[i].x,c[i].y,c[i].z);
for( i = 0; i < 3;
i ++ )
{
line(c[i].x,c[i].y,c[i
+ 4].x,c[i + 4].y);
line(c[i].x,c[i].y,c[i+1].x,c[i+1].y);
line(c[i+4].x,c[i+4].y,c[i+5].x,c[i+5].y);
}
line(c[0].x,c[0].y,c[3].x,c[3].y);
line(c[4].x,c[4].y,c[7].x,c[7].y);
line(c[3].x,c[3].y,c[7].x,c[7].y);
outtextxy(10,410,"Chon
mat chieu: ");
outtextxy(10,420,"xoy:
Bam so 1.");
outtextxy(10,430,"xoz:
Bam so 2.");
outtextxy(10,440,"yoz:
Bam so 3.");
outtextxy(10,450,"Bam
so 4 de ket thuc");
char m;
do{
m = getch();
for(i = 0;i < 8; i
++)
c[i]= l[i];
switch (m)
{
case '1' :{
chieumat(c,1,*(d));
break;
}
case '2' :{
chieumat(c,2,*(d));
break;
}
case '3' :
{
chieumat(c,3,*(d)) ;
break;
}
}
}while( m !='4');
closegraph();
}
za thế
Trả lờiXóahay thế mà cứ giữ...
Trả lờiXóahay thế mà cứ giữ...
Trả lờiXóaghê nha
Trả lờiXóa