Trường đại học công nghiệp Hà NộiKhoa công nghệ thông tin ---o0o---Bài tập lớn môn : Đồ họa máy tính Đề tài : vẽ tam giác và các phép biến đổi Nhóm thực hiện: Nhóm 30 Thành viên trong
Trang 1Trường đại học công nghiệp Hà Nội
Khoa công nghệ thông tin
-o0o -Bài tập lớn môn :
Đồ họa máy tính
Đề tài : vẽ tam giác và các phép biến đổi
Nhóm thực hiện: Nhóm 30
Thành viên trong nhóm: 1 Dương Vương
2 Nguyễn Văn Quý
Giáo viên hướng dẫn: Nguyễn Thị Cẩm Ngoan
1
Hà Nội, tháng 2 năm 2013
Trang 2Yêu Cầu Thực Hiện:
Viết chương trình vẽ 1 tam giác Toạ độ các đỉnh được nhập từ bàn phím, mỗi cạnh có một màu khác nhau.Sử dụng các phép biến đổi hình:tịnh tiến, tỉ lệ, quay tâm
0, đối xứng qua điểm, đối xứng qua đường thẳng.
Trang 3MỤC LỤC
CHƯƠNG I: PHÂN TÍCH BÀI TOÁN 4
I.Vẽ Tam Giác 4
Tạo khung nhìn 4
Tỉ lệ phóng to 4
Xây dựng bộ công cụ 2D 4
II.Các phép biến hình cơ bản 6
1.Phép tịnh tiến 6
2.Phép biến đổi tỉ lệ 8
3.Phép đối xứng 10
4.Phép quay 14
CHƯƠNG 2 : CÀI ĐẶT CHƯƠNG TRÌNH 15
3
Trang 4I.PHÂN TÍCH BÀI TOÁN
I.Vẽ Tam Giác
Chuyển bài toán vẽ tam giác trong không gian thực về bài toán vẽ trong không gian 2D Xây dựng bộ công cụ chuyển đổi :
void cuaSo(float x1, float y1, float x2, float y2)
{
xw1 = x1; xw2 = x2;
yw1 = y1; yw2 = y2;
}
// Tao khung nhin
void khungNhin(int x1, int y1, int x2, int y2)
{
xv1 = x1; yv1 = y1; xv2 = x2; yv2 = y2;
// Ti le phong to
tlx = (xv2 - xv1) / (xw2 - xw1);
tly = (yv2 - yv1) / (yw2 - yw1);
}
// Xay dung bo cong cu 2D
void chuyenDen(float x, float y)
{
int xm = (int)(tlx * (x - xw1) + xv1 + 0.5);
int ym = (int)(tly * (yw2 - y) + yv1 + 0.5);
moveto(xm, ym);
Trang 5void veDen(float x, float y)
{
int xm = (int)(tlx * (x - xw1) + xv1 + 0.5);
int ym = (int)(tly * (yw2 - y) + yv1 + 0.5);
lineto(xm, ym);
}
Dựa vào bộ công cụ vừa cài đặt ta có thể cài đặt vẽ tam giác với các cạnh được nhập vào từ bàn phím , mỗi cạnh lại có màu khác nhau
void veTamGiac(int x1, int y1, int x2, int y2, int x3, int y3)
{
float x, y;
x = x1; y = y1; chuyenDen(x,y);setcolor(2);
x = x2; y = y2; veDen(x,y);setcolor(3);
x = x3; y = y3; veDen(x,y);setcolor(4);
x = x1; y = y1; veDen(x,y);
}
5
Trang 6II.Các phép biến hình cơ bản
Bản chất của các phép biến đổi hình học là sự thay đổi các mô tả về tọa độ của đối tượng từ đó làm đối tượng thay đổi về hướng, kích thước cũng như hình dạng
1.Phép tịnh tiến
Ảnh của phép tịnh tiến theo vector (a,b) của điểm P(x,y) là điểm Q(x*,y*)
b y y
a x x
*
* Vector tịnh tiến (a,b) còn gọi là “vector độ dời” Chúng ta có thể áp dụng quy tắc trên cho mọi điểm của đối tượng để dịch chuyển nó Đơn giản hơn, để tịnh tiến một đa giác chỉ cần tịnh tiến các đỉnh của nó rồi vẽ lại đa giác mới Tương tự, đối với đường tròn, ellip ta tịnh tiến tâm của chúng tới
vị trí mới rồi vẽ lại
Trang 7Nếu gọi ttx và tty lần lượt là độ dời theo trục hoành và trục tung thì tọa độ của điểm mới Q(x’,y’) sau khi tịnh tiến điểm P(x,y) sẽ là:
Khi đó (ttx,tty) được gọi là vecto tịnh tiến hay độ dời
Ma trận biến đổi
Thuật toán cài đặt
void TinhTien(float &x,float &y,float ttx,float tty)
{
x=x+ttx;
y=y+tty;
}
7
1 0 0
0 1 0 tlx tly 0
T=
Trang 8Hình 2.1 Phép tịnh tiến
2.Phép biến đổi tỉ lệ
Phép biến đổi tỉ lệ làm thay đổi kích thước của đối tượng Để co hay dãn tọa độ của một điểm P(x,y) theo trục hoành và trục tung lần lượt là tlx, tly ta nhân lần lượt tlx và tly vào các tọa độ của P
Ma trận biến đổi
Khi các giá trị tlx và tly nhỏ hơn 1 thì phép biến đổi tỉ lệ thu nhỏ đối tượng và ngược lại khi các phép biến đổi lớn hơn 1 phép biến đổi phóng to đối tượng
Khi tỉ lệ tlx=tly ta gọi đó là phép đồng dạng Phép đồng dạng là phép biến đổi bảo toàn tính cân xứng của đối tượng
x’=x*tlx;
y’=y*tly;
Trang 9 Tâm tỉ lệ là điểm không bị thay đổi qua các phép biến đổi tỉ lệ.
Nhận xét : Khi phép biến đổi tỉ lệ thu nhỏ đối tượng, đối tượng sẽ được dời về gần gốc tọa độ hơn, tương tự khi phóng lớn đối tượng , đối tượng sẽ được dịch chuyển xa gốc tọa độ hơn
Thuật toán cài đặt
void BienDoiTiLe(float &x,float &y,float tlx,float tly)
{
x=x*tlx; y=y*tly;
}
9
Trang 10Hình 1.2 Phép biến đổi tỉ lệ
3.Phép đối xứng
Phép đối xứng trục có thể xem là phép quay 1800 quanh trục đối xứng Phép đối xứng qua trục hoành và trục tung có ma trận lần lượt là:
1 0 0
0 1 0
0 0 1 ,
1 0 0
0 1 0
0 0 1
Oy
M
Thuật toán cài đặt
void DoiXung(float x,float y,float xtam,float ytam)
{
x=2*xtam-x;
y=2*ytam-y;
}
Trang 11Hình 1.3.1 Phép đối xứng với tâm bất kì
Phép đối xứng qua đường thẳng X bất kỳ
11
Trang 12Phép đối xứng qua đường thẳng Y bất kỳ
Trang 13Phép đối xứng qua đường thẳng ax+by+c = 0
13
Trang 144.Phép quay
Phép quay làm thay đổi hướng của đối tượng Để xác định phép quay, ta cần biết tâm quay và góc quay Phép quay điểm P(x,y) quanh gốc tọa độ một góc tạo thành điểm ảnh Q(x*,y*) có công thức như sau:
cos sin
.
*
sin cos
.
*
y x
y
y x
x
Thuật toán cài đặt
void Quay(float x,float y,float goc)
{
goc=(pi/180)*goc;
float a=x,b=y;
x=a*cos(goc)-b*sin(goc);
y=a*sin(goc)+b*cos(goc);
}
Phép quay quanh một điểm
1800
Trang 15Phép quay quanh gốc 0 một góc bất kỳ
CHƯƠNG 2 : CÀI ĐẶT CHƯƠNG TRÌNH
#include<math.h>
#include<iostream.h>
#include<conio.h>
#include<dos.h>
#include<graphics.h>
// Khai bao
int xv1, yv1, xv2, yv2;
float x,y,xw1, yw1, xw2, yw2, tlx, tly,a,b,c;
// Ham xac dinh cua so
void cuaSo(float x1, float y1, float x2, float y2)
{
xw1 = x1; xw2 = x2;
yw1 = y1; yw2 = y2;
}
// Tao khung nhin
15
Trang 16void khungNhin(int x1, int y1, int x2, int y2)
{
xv1 = x1; yv1 = y1; xv2 = x2; yv2 = y2;
// Ti le phong to
tlx = (xv2 - xv1) / (xw2 - xw1);
tly = (yv2 - yv1) / (yw2 - yw1);
}
// Xay dung bo cong cu 2D
void chuyenDen(float x, float y)
{
int xm = (int)(tlx * (x - xw1) + xv1 + 0.5);
int ym = (int)(tly * (yw2 - y) + yv1 + 0.5);
moveto(xm, ym);
}
void veDen(float x, float y)
{
int xm = (int)(tlx * (x - xw1) + xv1 + 0.5);
int ym = (int)(tly * (yw2 - y) + yv1 + 0.5);
lineto(xm, ym);
}
// Ve truc toa do
void veTruc()
{
setcolor(WHITE);
// Ve truc Ox
chuyenDen(xw1, 0);
veDen(xw2, 0);
chuyenDen(xw2-0.4,-0.5);
outtext("x");
// Ve truc Oy
chuyenDen(0, yw1);
veDen(0, yw2);
chuyenDen(-0.8,yw2);
outtext("y");
chuyenDen(-1,-0.4);
outtext("O");
x=xw1+1;
while(x<xw2)
{
y=0;
chuyenDen(x,y-0.04);
veDen(x,y+0.04);
x=x+1;
Trang 17}
y=yw1+1;
while(y<yw2)
{
x=0;
chuyenDen(x-0.04,y);
veDen(x+0.04,y);
y=y+1;
}
chuyenDen(-0.2,yw2-0.2);
veDen(0,yw2);veDen(0.2,yw2-0.2);
chuyenDen(xw2-0.2,-0.2);
veDen(xw2,0);veDen(xw2-0.2,0.2);
}
//Ve duong thang ax+by+c=0
void VeDuong(float a,float b,float c)
{
if(a==0)
{
chuyenDen(xw1,-c/b);
veDen(xw2,-c/b);
}
if(b==0)
{
chuyenDen(-c/a,yw1);
veDen(-c/a,yw2);
}
if(a*b!=0)
{
if((yw1<=(-a*xw1-c)/b)&&(-a*xw1-c)/b<=yw2)
{
chuyenDen(xw1,(-a*xw1-c)/b);
veDen(xw2,(-a*xw2-c)/b);
}
else
{
chuyenDen((-c-b*yw2)/a,yw2);
veDen((-c-b*yw1)/a,yw1);
}
}
}
void DXDuong(float m,float n,float a,float b,float c)
{
17
Trang 18float t=(a*m+b*n+c)/(a*a+b*b);
m=m-2*t*a;
n=n-2*t*b;
// cout<<"toa do diem m sau khi doi xung"<<m;cout<<"toa do diem n sau khi doi xung"<<n;
}
// Ve tam giac
void veTamGiac(float x1, float y1, float x2, float y2, float x3, float y3)
{
float x, y;
x = x1; y = y1; chuyenDen(x,y);setcolor(2);
x = x2; y = y2; veDen(x,y);setcolor(3);
x = x3; y = y3; veDen(x,y);setcolor(4);
x = x1; y = y1; veDen(x,y);
}
main(void)
{ float a1,a2,b1,b2,c1,c2,t1,t2,t3,Ma1,Ma2,Mb1,Mb2,Mc1,Mc2; int n1,n2,k1,k2;
float goc,a,b,c;
int M1,M2;
int X,Y;
int driver = 6, mode = 0;
initgraph(&driver, &mode, "");
// Ve khung nhin
cuaSo(-20, -20, 20, 20);
khungNhin(10, 10, 500, 500);
setcolor(14);
//rectangle(10, 10, 400, 400);
// Ve truc toa do (cho de nhin)
veTruc();
// ve tam giac
cout<<"nhap vao toa do dinh A \n";
cout<<" a1 = "; cin>>a1;
cout<<" a2 = "; cin>> a2;
cout<<"nhap vao toa do dinh B \n";
cout<<" b1 = "; cin>>b1;
cout<<" b2 = "; cin>> b2;
cout<<"nhap vao toa do dinh C \n";
cout<<" c1 = "; cin>>c1;
cout<<" c2 = "; cin>> c2;
veTamGiac(a1,a2,b1,b2,c1,c2);
Trang 19// /*
// tinh tien tam giac
cout<<"nhap vao vec to tinh tien n\n";
cout<<" n1 : "; cin>>n1;
cout<<" n2 : "; cin>>n2;
veTamGiac(a1+n1,a2+n2,b1+n1,b2+n2,c1+n1,c2+n2);
// ti le tam giac
cout<< "nhap vao he so ti le k \n";
cout<<" k1 : ";cin>> k1;
cout<<" k2 : "; cin>>k2;
veTamGiac(a1*k1,a2*k2,b1*k1,b2*k2,c1*k1,c2*k2);
// doi xung qua diem M bat ky
cout<<"nhap vao toa do diem M \n"<<" M1 : "; cin>>M1;
cout<<" M2 :";cin>>M2;
veTamGiac(2*M1-a1,2*M2-a2,2*M1-b1,2*M2-b2,2*M1-c1,2*M2-c2);
// quay tam giac quanh tam O
cout<<"nhap vao goc quay \n"; cin>>goc;
goc=(3.14/180)*goc;
veTamGiac(a1*cos(goc)-a2*sin(goc),a1*sin(goc)
+a2*cos(goc),b1*cos(goc)-b2*sin(goc),b1*sin(goc)
+b2*cos(goc),c1*cos(goc)-c2*sin(goc),c1*sin(goc)+c2*cos(goc));
// */
// doi xung qua duong thang X
cout<<"nhap vao duong thang X \n";
cin>> X;
setcolor(11);
chuyenDen(X, 0);
veDen(X, 20);
veDen(X, -20);
// Ve tam giac va anh cua no
veTamGiac(2*X-a1, a2, 2*X-b1, b2, 2*X-c1, c2);
// doi xung qua duong thang Y
cout<<"nhap vao duong thang Y \n";
cin>> Y;
19
Trang 20setcolor(14);
chuyenDen(0,Y);
veDen(20,Y);
veDen(-20,Y);
veTamGiac(a1,2*Y-a2,b1,2*Y-b2,c1,2*Y-c2);
//Doi xung qua duong thang ax+by+c=0
cout<<"nhap vao cac he so cua duong thang ax +by +c =0 \n"; cout<<" a = "; cin>>a;
cout<<" b = "; cin>>b;
cout<<" c = "; cin>>c;
VeDuong(a,b,c);
// ve diem doi xung cua A
t1=(a*a1+b*a2+c)/(a*a+b*b);
Ma1=a1-2*t1*a;
Ma2=a2-2*t1*b;
// ve diem doi xung cua B
t2=(a*b1+b*b2+c)/(a*a+b*b);
Mb1=b1-2*t2*a;
Mb2=b2-2*t2*b;
// ve diem doi xung cua C
t3=(a*c1+b*c2+c)/(a*a+b*b);
Mc1=c1-2*t3*a;
Mc2=c2-2*t3*b;
veTamGiac(Ma1,Ma2,Mb1,Mb2,Mc1,Mc2);
getch();
closegraph();
}