Tải bản đầy đủ (.pdf) (19 trang)

Vẽ ngôi sao quay và Vẽ ôtô chạy qua lại trong Đồ họa máy tính

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (194.98 KB, 19 trang )

Bi tập lớn môn đồ hoạ máy tính
vẽ hình chuyển động

Nhóm thực hiện:
Đinh Văn Phong
Phạm Đình Thanh
Nguyễn Đình Thọ
Nguyễn Nh Vũ
Trần Thị Trang
Đỗ Thị Thanh Vân
Giáo viên hớng dẫn:
Nguyễn Văn Trờng

Tên đề ti
Đề 2:
I. Vẽ sao năm cánh quay quanh tâm, dùng phím mũi tên di chuyển sao đi khắp
màn hình.
II. Vẽ ôtô chạy qua lại trên đờng nằm ngang.


1
I. Vẽ sao năm cánh quay quanh tâm, dùng phím mũi tên di chuyển sao
đi khắp màn hình.
I.1. ý tởng:

2
O
x
y
a. Mô tả hình sao 5 cánh:
- Hình sao 5 cánh có dạnh nh hình bên:


- Một ngôi sao 5 cánh có đặc điểm :
Năm đỉnh cách đều tâm O một khoảng r
(OA1=OA2=OA3=OA4=OA5=r).
=> Các đỉnh A1,A2, ,A5 nằm trên đờng tròn tâm O bán kính r.
Hai đỉnh kề nhau tạo với nhau một góc 72
0

(góc A
1
OA
2
=góc A
2
OA
3
=góc A
3
OA
4
=góc A
4
OA
5
=góc A
5
OA
1
=72
0
).

















b. ý tởng vẽ hình sao (trong Mode 19)
* Hệ toạ độ trong mode 19:

Với: O(0,0) ;
Ox có số điểm ảnh tối đa là 200
pixel ;
Oy có số điểm ảnh tối đa là 320
pixel ;
* Vẽ hình ông sao:( Gắn vào hệ toạ độ xO
1
y)
- Toạ độ tâm là O
1
(xc,yc) ;

- Khoảng cách từ tâm đến đỉnh là r ;
- Xác định tọa độ các đỉnh:
+ Chọn A(x,y) với x=xc+r, y=yc.
+ Toạ độ đỉnh A1 (xo,yo).Ta chọn xo=xc-r, yo=yc bằng phép quay điểm
A quanh tâm O
1
theo hớng +

một góc

=

(=3.14).
+ Theo đặc điểm của ông sao ta có thể xác định các đỉnh còn lại bằng cách
sau:
Quay A quanh tâm O
1
theo
hớng + một góc
180
*72

+

ra
góc A2
Quay A quanh tâm O
1
theo
hớng +


một góc
180
*2*72

+

ra
góc A3
O
1
Quay A quanh tâm O
1
theo
hớng +

một góc
180
*3*72

+

ra
góc A4
Quay A quanh tâm O
1
theo
hớng +

một góc

180
*4*72

+

ra
góc A5

Khi xác định đợc các đỉnh ta bắt đầu nối các đỉnh với nhau thành hình ông
sao (A1 với A3, A4), (A2 với A4, A5), (A3 với A5).
Kết quả ta đợc hình cần tìm:

3
c. Di chuyển hình sao:
* Sao quay quanh tâm:
Thực hiện phép quay hình sao quanh gốc O
1
với góc a= . Thực hiện
360 lần quay hình sao ban đầu theo chiều dơng (âm) thì quay hình sao đợc
một vòng quanh gốc O
180/)*1(
1
. Mỗi lần quay thực hiện theo nguyên tắc:
Góc quay tỉ lệ thuận với số lần quay (lần 1: a= , lần 2:
, , lần 360:
180/)*1(
180/)*2( 180/)*360(

).
Vẽ hình sao với màu c, sau đó trễ thời gian t, rồi vẽ hình sao với màu

trùng với màu nền.
* Sao di chuyển ( dùng phím mũi tên để di chuyển):
Ta lập trình trong TC 3 vì vậy dùng hàm kbhit () để xác định một phím khi
nào đợc ấn. Chú ý các phím mũi tên có mã phím là: Phải:77, Trái:75,
Xuống:80, Lên:72. Quá trình di chuyển đợc thực hiện nh sau:
- Khi thực hiện di chuyển lên trên ta thực hiện phép tịnh tiến hình sao theo
vectơ i có toạ độ (-1,0);
- Khi thực hiện di chuyển xuống trên ta thực hiện phép tịnh tiến hình sao
theo vectơ i có toạ độ (1,0);
- Khi thực hiện di chuyển sang trái trên ta thực hiện phép tịnh tiến hình
sao theo vectơ i có toạ độ (0,-1);
- Khi thực hiện di chuyển sang phải trên ta thực hiện phép tịnh tiến hình
sao theo vectơ i có toạ độ (0,1);

I.2 Thuật giải:
* Vẽ hình sao:
Vẽ hình sao với tâm có toạ độ là (xc,yc), khoảng cách từ tâm đến đỉnh là r,
màu c. Đỉnh A1(xo,yo) với xo, yo và tạo với trục Ox góc afa, các đỉnh A2 A5 có
toạ độ đợc lu trữ với hai mảng một chiều. Cụ thể: A2(a[1],b[1]),
A3(a[2],b[2]), A4(a[3],b[3]), A5(a[4],b[4]).


4
void ve_hinhsao(int afa, int xo, int yo,int xc,int yc,int r,int c)
{
double i; int a[5], b[5];
for (i=1;i<5;i+=1)
{
a[i]=ceil(r*cos(afa+(72*3.14*i)/180))+xc;
b[i]=ceil(r*sin(afa+(72*3.14*i)/180))+yc;

}
dt(xo,yo,a[2],b[2],c); // Nối A1 với A3
dt(xo,yo,a[3],b[3],c); // Nối A1 với A4
dt(a[1],b[1],a[3],b[3],c); // Nối A2 với A4
dt(a[1],b[1],a[4],b[4],c); // Nối A2 với A5
dt(a[2],b[2],a[4],b[4],c); // Nối A3 với A5
}

*Sao vừa quay quanh tâm vừa di chuyển:
Vẽ sao quanh tâm một vòng theo chiều dơng. Vị trí ban đầu của hình sao có
tâm (xc,yc), khoảng cách từ tâm đến đỉnh là r, đỉnh A1(xo,yo) tạo với Ox góc a.
void sao_dichuyen(double a,int xo,int yo,int xc,int yc,int r,int c)
{
ve_hinhsao(a,xo,yo,xc,yc,r,c);
delay(50); // trễ một khoảng thời gian
ve_hinhsao(a,xo,yo,xc,yc,r,0);
char c1;
int i=0;
while (i<=360)
{
i++; // Quay quanh tâm
xo=ceil(r*cos(a+i*3.14/180))+xc;
yo=ceil(r*sin(a+i*3.14/180))+yc;
ve_hinhsao(a+i*3.14/180,xo,yo,xc,yc,r,c);
delay(50); // trễ một khoảng thời gian
ve_hinhsao(a+i*3.14/180,xo,yo,xc,yc,r,0);
if (kbhit()) // Di chuyển hình sao dùng 4 phím mũi tên
{
if (c1!=27)
{

c1 = getch();
if (c1==77) yc++;
else if (c1==75) yc ;
else if (c1==80) xc++;

5
else if (c1==72) xc ;
}
else
break;
}
}
}

I. 3: Ch−¬ng tr×nh:
/* Ch−¬ng tr×nh dïng 4 phÝm mòi tªn ®Ó di chuyÓn sao, phÝm c¸ch ®Ó ®æi chiÒu
quay phÝm ESC ®Ó tho¸t khái ch−¬ng tr×nh. */
#include<dos.h>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<conio.h>

void mode(int m)
{
union REGS r;
r.h.ah=0;
r.h.al=m;
int86(16,&r,&r);
}


void point(int x, int y,int c)
{
if ((x>=0)&&(x<200)&&(y>=0)&&(y<320))
*((char far*) 0xA0000000 + 320*x+y)=c;
}

int readpoint(int x, int y)
{
if ((x>=0)&&(x<200)&&(y>=0)&&(y<320))
return *((char far*) 0xA0000000 + 320*x+y);
}

void loang(int x,int y, int c, int c1)
{
if (readpoint(x,y)==c)
{
point(x,y,c1);

6
loang(x+1,y,c,c1);
loang(x,y+1,c,c1);
loang(x-1,y,c,c1);
loang(x,y-1,c,c1);
}
}

void maunen()
{
for (int i=1;i<=200;i++)

for (int j=1;j<=320;j++)
point(i,j,39);
}

void dt(int x1, int y1, int x2, int y2, int color)
{
int d, ax, ay, sx, sy, dx, dy;
dx = x2-x1;
ax = abs(dx) << 1;
if (dx < 0) sx = -1; else sx = 1;
dy = y2-y1;
ay = abs(dy) << 1;
if (dy < 0) sy = -1; else sy = 1;
point(x1, y1, color);
if (ax > ay)
{
d = ay-(ax >> 1);
while (x1 != x2)
{
if (d >= 0)
{
y1 = y1 + sy;
d = d - ax;
}
x1 = x1 + sx;
d = d + ay;
point(x1, y1, color);
} //while
}
else

{
d = ax-(ay >> 1);

7
while (y1 != y2)
{
if (d >= 0)
{
x1 = x1 + sx;
d = d - ay;
}
y1 = y1 + sy;
d = d + ax;
point(x1, y1, color);
} //while
} //if
} //end drawLine

void ve_hinhsao(double afa,int xo,int yo,int xc,int yc,int r,int c)
{
int a[5],b[5],h[5],k[5];
double i;
h[5]=ceil((2*r/3)*cos(afa))+xc;
k[5]=ceil((2*r/3)*sin(afa))+yc;
for (i=1;i<5;i+=1)
{
a[i]=ceil(r*cos(afa+(72*M_PI*i)/180))+xc;
h[i]=ceil((2*r/3)*cos(afa+(72*M_PI*i)/180))+xc;
b[i]=ceil(r*sin(afa+(72*M_PI*i)/180))+yc;
k[i]=ceil((2*r/3)*sin(afa+(72*M_PI*i)/180))+yc;

}
dt(xo,yo,a[2],b[2],c);
dt(xo,yo,a[3],b[3],c);
dt(a[1],b[1],a[3],b[3],c);
dt(a[2],b[2],a[4],b[4],c);
dt(a[1],b[1],a[4],b[4],c);
loang(xc,yc,39,c);
for (i=1;i<=5;i+=1)
loang(h[i],k[i],39,c);
}

void sao_dc(double a,int xo,int yo,int xc,int yc,int r,int c)
{
ve_hinhsao(a,xo,yo,xc,yc,r,c);
delay(50);
ve_hinhsao(a,xo,yo,xc,yc,r,0);

8
char c1;
int i=0;int t=1;
while (1)
{
if (i==360) i=0;
else i+=t;
maunen();
xo=ceil(r*cos(a+i*M_PI/180))+xc;
yo=ceil(r*sin(a+i*M_PI/180))+yc;
ve_hinhsao(a+i*M_PI/180,xo,yo,xc,yc,r,c);
delay(50);
ve_hinhsao(a+i*M_PI/180,xo,yo,xc,yc,r,0);

if (kbhit())
{
if (c1!=27)
{
c1 = getch();
if (c1==77) {if(yc<320-r) yc++;}
else if (c1==75) {if(yc>r) yc ;}
else if (c1==80) {if(xc<200-r) xc++;}
else if (c1==72) {if(xc>r) xc ;}
else if (c1==32) t=-t;
}
else
break;
}
}
}

void main()
{
int lc,xo,yo,xc,yc,c,r;
xc=100;yc=160;c=43;r=50;
xo=xc-r;yo=yc;
mode(19);
double a=M_PI;
sao_dc(a,xo,yo,xc,yc,r,c);
getch();
mode(3);
}




9
KÕt qu¶ ch−¬ng tr×nh:

10
II. Vẽ ôtô chạy qua lại trên đờng nằm ngang.
Hình vẽ minh họa:















II.1 ý tởng
a.

Vẽ ôtô:
Nh hình vẽ thì ta thấy ôtô đợc tạo bởi 3 hình chữ nhật và hai hình tròn

A
D


O
1
F
G M
E


N

B
H
C



Ta có thể vẽ đợc hình chữ nhật khi biết toạ độ của hai đỉnh đối nhau và vẽ đợc
hình tròn khi biết tâm và bán kính. Khi đó ta có ý tởng vẽ ôtô nh sau:
Chọn đỉnh O
1
đầu tiên từ đó ta xác định toạ độ các điểm A,B,C,E,G,N từ O
1
. Ta
vẽ hình chữ nhật ADCB từ hai đỉnh A và C, hình chữ nhật EFHB từ hai đỉnh E và
B, hình chữ nhật CGMN từ hai đỉnh G và N, Đờng tròn tâm B từ đỉnh B, đờng
tròn tâm C từ đỉnh C.
b.

Di chuyển ôtô:
Di chuyển sang trái theo vectơ có toạ độ (0,-1);

Di chuyển sang phải theo vectơ có toạ độ (0,1);



11
II.2 Giải thuật
Vẽ ôtô có màu là c ở vị trí mà toạ độ điểm giữa ôtô là (xc,yc)

void ve_oto(int xc, int yc, int c)
{
ve_hcn(xc-10,yc-30,xc+10,yc+30,c);
ve_hcn(xc-3,yc-50,xc+10,yc-30,c);
ve_hcn(xc-3,yc+30,xc+10,yc+50,c);
ve_dtr(xc+10,yc-30,c);
ve_dtr(xc+10,yc+30,c);
}

II.3 Chơng trình
/* Chơng trình dùng phím cách để đổi hớng đi của ôtô, phím ESC để thoát
khỏi chơng trình*/
#include<dos.h>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<conio.h>
#include<iostream.h>

void mode(int m)
{
union REGS r;

r.h.ah=0;
r.h.al=m;
int86(16,&r,&r);
}

void point(int x, int y,int c)
{
if ((x>=0)&&(x<200)&&(y>=0)&&(y<320))
*((char far*) 0xA0000000 + 320*x+y)=c;
}

void ve_hcn(int x1,int y1,int x2,int y2,int c)
{
int i;
for (i=y1;i<=y2;i++)
point(x1,i,c);
if (x1==x2) return;

12
for (i=y1;i<=y2;i++)
point(x2,i,c);
for (i=x1+1;i<x2;i++)
point(i,y1,c);
if (y2==y1) return;
for (i=x1+1;i<x2;i++)
point(i,y2,c);
}

void tomau_hcn(int x1,int y1,int x2,int y2,int c)
{

int i,j;
for(i=x1;i<=x2;i++)
for(j=y1;j<=y2;j++)
point(i,j,c);
}

void ve_dtr(int xc,int yc,int r, int c)
{
int x,y;
x=xc+r;y=yc;
for (int i=0;i<=360;i++)
{
x=ceil(r*cos(i*3.14/180))+xc;
y=ceil(r*sin(i*3.14/180))+yc;
point(x,y,c);
}
}

void ve_oto(int xc, int yc, int c, int b)
{
ve_hcn(xc-10,yc-30,xc+10,yc+30,c);
tomau_hcn(xc-10,yc-30,xc+10,yc+30,c);
ve_hcn(xc-3,yc-50,xc+10,yc-30,c);
tomau_hcn(xc-3,yc-50,xc+10,yc-30,c);
ve_hcn(xc-3,yc+30,xc+10,yc+50,c);
tomau_hcn(xc-3,yc+30,xc+10,yc+50,c);
for(int i=1; i<=7;i++) ve_dtr(xc+10,yc-30,i,b);
for(i=1; i<=7;i++) ve_dtr(xc+10,yc+30,i,b);
}


13

void main()
{
int t=0;
mode(19);
for(int i=1;i<=350;i++)
{
t=t+10;
point(100,i,255);
point(99,i,255);
}
int h=1;
i=0;
char c1;
while (1)
{
i=i+h;
if (i==375||i==-55) h=-h;
ve_oto(80,i,12,21);
delay(50);
ve_oto(80,i,0,0);

if (kbhit())
{
if (c1!=27)
{
c1=getch();
if (c1==32) h=-h;
}

else break;
}
}
getch();
mode(3);
}

14
* Chơng trinh ứng dụng: (Chơng trình cải tiến của đề tài vẽ ôtô)
/* Mô tả: Khi ôtô đến vị trí của khách sẽ dừng lại đợi khách lên xe rồi đi tiếp.
Khi đi hết đờng thì một xe khác sẽ quay về bến và trả khách.*/
#include<dos.h>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<conio.h>
#include<iostream.h>

void mode(int m)
{
union REGS r;
r.h.ah=0;
r.h.al=m;
int86(16,&r,&r);
}

void point(int x, int y,int c)
{
if ((x>=0)&&(x<200)&&(y>=0)&&(y<320))
*((char far*) 0xA0000000 + 320*x+y)=c;

}
void ve_hcn(int x1,int y1,int x2,int y2,int c)
{
int i;
for (i=y1;i<=y2;i++)
point(x1,i,c);
if (x1==x2) return;
for (i=y1;i<=y2;i++)
point(x2,i,c);
for (i=x1+1;i<x2;i++)
point(i,y1,c);
if (y2==y1) return;
for (i=x1+1;i<x2;i++)
point(i,y2,c);
}
void tomau_hcn(int x1,int y1,int x2,int y2,int c)
{
int i,j;
for(i=x1;i<=x2;i++)
for(j=y1;j<=y2;j++)
point(i,j,c);
}

15
void dt1(int x1, int y1, int x2, int y2, int color)
{
int d, ax, ay, sx, sy, dx, dy;

dx = x2-x1;
ax = abs(dx) << 1;

if (dx < 0) sx = -1; else sx = 1;

dy = y2-y1;
ay = abs(dy) << 1;
if (dy < 0) sy = -1; else sy = 1;

point(x1, y1, color);

if (ax > ay) {
d = ay-(ax >> 1);
while (x1 != x2) {
if (d >= 0) {
y1 = y1 + sy;
d = d - ax;
}
x1 = x1 + sx;
d = d + ay;
point(x1, y1, color);
} //while
} else {
d = ax-(ay >> 1);
while (y1 != y2) {
if (d >= 0) {
x1 = x1 + sx;
d = d - ay;
}
y1 = y1 + sy;
d = d + ax;
point(x1, y1, color);
} //while

} //if
} //end drawLine

void ve_dtr(int xc,int yc,int r, int c)
{
int x,y;
x=xc+r;y=yc;
for (int i=0;i<=360;i++)

16
{
x=ceil(r*cos(i*3.14/180))+xc;
y=ceil(r*sin(i*3.14/180))+yc;
point(x,y,c);
}
}
void ve_oto(int xc, int yc, int c, int b)
{
ve_hcn(xc-10,yc-30,xc+10,yc+30,c);
tomau_hcn(xc-10,yc-30,xc+10,yc+30,c);
ve_hcn(xc-3,yc-50,xc+10,yc-30,c);
tomau_hcn(xc-3,yc-50,xc+10,yc-30,c);
ve_hcn(xc-3,yc+30,xc+10,yc+50,c);
tomau_hcn(xc-3,yc+30,xc+10,yc+50,c);
for(int i=1; i<=7;i++) ve_dtr(xc+10,yc-30,i,b);
for(i=1; i<=7;i++) ve_dtr(xc+10,yc+30,i,b);
}
void nguoi(int x1, int y1,int cc, int c)
{
ve_dtr(x1,y1,4,c);

for(int i=1; i<=cc;i++)
point(x1+3+i,y1,c);
dt1(x1+3+i,y1,x1+12+i,y1-6,c);
dt1(x1+3+i,y1,x1+12+i,y1+6,c);
int k=y1-10;
for(int j=1;j<=20;j++)
{
point(x1+10,k,c);
k++;
}
}
void benxe()
{
ve_hcn(20,150,50,250,11);
ve_hcn(21,151,49,249,11);
ve_hcn(22,152,48,248,11);
ve_hcn(23,153,47,247,11);
for(int i=50;i<=98;i++)
{
point(i,155,7);
point(i,154,7);
point(i,245,7);
point(i,244,7);
}

17
}
/*void cay(int x,int y,int cc,int cr,int c)
{
dt1(x,y-cr,x-cc,y-cr/2,c);

dt1(x,y+cr,x-cc,y+cr/2,c);
for(int i=1; i<=20;i++) ve_dtr(x-cc-7,y,i,c);
} */
void cay(int x,int y,int cc,int cr,int c)
{
for(int i=y-cr;i<=y+cr;i++)
dt1(x,i,x-cc,i,8);
for( i=1; i<=20;i++) ve_dtr(x-cc-21,y,i,c);
}
void main()
{
int t=0,k=2,m=2;
mode(19);
for(int i=1;i<=350;i++)
{
t=t+10;
point(100,i,255);
point(99,i,255);
}
benxe();
cout<<"\n\n\n\n BUS STOP";
nguoi(65,200,20,k);
cay(98,100,50,2,2);
cay(98,290,70,2,2);
cay(98,20,30,5,2);
int h=1;
i=0;
k=m;
int c=4;
char c1;

while (1)
{
benxe();
cay(98,100,50,2,2);
cay(98,290,70,2,2);
cay(98,20,30,5,2);
nguoi(65,200,20,k);
i=i+h;
if (i==375||i==-55)
{

18
h=-h;
c++;
}
ve_oto(80,i,c,8);
if (i==200)
{ delay(1000);
m=-m;
k=k+m;
}

delay(50);
ve_oto(80,i,0,0);
if (kbhit())
{ if (c1!=27)
{
c1=getch();
if (c1==32) h=-h;
}

else break;
}
}
getch();
mode(3);
}

19

×