Bài giảng Đồ họa máy tính - Chương 3: Xây dựng công cụ vẽ hình ảnh

Cửa sổ và khung nhìn

Phép biến đổi từ cửa sổ sang khung nhìn

Giải thuật cắt xén

Xây dựng lớp Canvas phục vụ cho việc vẽ hình ảnh

Vẽ tương đối và đồ hoạ con rùa

Tạo hình ảnh từ đa giác đều

Vẽ đường tròn và cung tròn

Biểu diễn và vẽ đường cong theo dạng tham số

 

ppt44 trang | Chuyên mục: Đồ Họa Máy Tính | Chia sẻ: tuando | Lượt xem: 432 | Lượt tải: 0download
Tóm tắt nội dung Bài giảng Đồ họa máy tính - Chương 3: Xây dựng công cụ vẽ hình ảnh, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
p1 với cạnh trái 
 else if ( p1 nằm bên phải ) cắt xén p1 với cạnh phải 
	 else if ( p1 nằm dưới ) cắt xén p1 với cạnh dưới 
 else if ( p1 nằm trên ) cắt xén p1 với cạnh trên 
	 } 
 else // p2 nằm ngoài 
	 { 
 if ( p2 nằm bên trái ) cắt xén p2 với cạnh trái 
 else if ( p2 nằm bên phải ) cắt xén p2 với cạnh phải 
	 else if ( p2 nằm dưới ) cắt xén p2 với cạnh dưới 
 else if ( p2 nằm trên ) cắt xén p2 với cạnh trên 
	 } 
	}while(1); 
} 
p1 
p2 
D 
C 
A 
B 
XÂY DỰNG LỚP CANVAS 
Mục đích: 
Cung cấp những tiện ích để vẽ các đối tượng như đường thẳng, đa giác v.v 
Cung cấp cách làm đơn giản để tạo cửa sổ ứng dụng, thiết lập cửa sổ khung nhìn, thiết lập ánh xạ biến đổi từ cửa sổ sang khung nhìn, cùng với những tiện ích trong đồ họa con rùa 
XÂY DỰNG LỚP CANVAS 
Các lớp hỗ trợ 
	 class Point2 
	{ 
	 public: 
	Point2() { x = y = 0.0f; } // constructor 
	 Point2(float xx, float yy) { x = xx; y = yy; } 
	void set(float xx, float yy) { x = xx; y = yy; } 
	float getX() { return x;} 
	float getY() { return y;} 
	void draw() { glBegin(GL_POINTS); 
	 glVertex2f((GLfloat)x, (GLfloat)y); 
	 glEnd(); 
	 } 
	 private: 
	float 	x, y; 
	}; 
XÂY DỰNG LỚP CANVAS 
Các lớp hỗ trợ 
	 class IntRect 
	{ 
	 public: 
	IntRect() { l = 0; r = 100; b = 0; t = 100; } 
	 IntRect( int left, int right, int bottom, int top) 
	{ l = left; r = right; b = bottom; t = top; } 
	void set( int left, int right, int bottom, int top) 
	{ l = left; r = right; b = bottom; t = top; } 
	void draw(); // draw this rectangle using OpenGL 
	 private: 
	int	l, r, b, t; 
	}; 
	class RealRect 
	{ 
	 giống như lớp intRect ngoại trừ dùng 
	float thay cho int 
	}; 
XÂY DỰNG LỚP CANVAS 
class Canvas{ 
	 public: 
	Canvas(int width, int height, char* windowTitle); 
	void setWindow(float l, float r, float b, float t); 
	void setViewport(int l, int r, int b, int t); 
	IntRect	 getViewport(); 
 	RealRect getWindow(); 
	float getWindowAspectRatio(); 
	void clearScreen(); 
	void setBackgroundColor(float r, float g, float b); 
	void setColor(float r, float g, float b); 
	void lineTo(float x, float y); 
	void lineTo(Point2 p); 
	void moveTo(float x, float y); 
	void moveTo(Point2 p); 
	 những phương thức khác sẽ được định nghĩa sau 
	 private: 
	Point2 CP; //current position in the world 
	IntRect viewport; // the current viewport 
	RealRect window; // the current window 
	 những biến thành viên khác sẽ được định nghĩa sau }; 
XÂY DỰNG LỚP CANVAS 
Canvas::Canvas(int width, int height, char* windowTitle) 
{ 
 char* argv[1]; 
 char dummyString[8]; 
 argv[0] = dummyString; 
 int argc = 1; 
 glutInit(&argc, argv); //initialize the tool kit 
 glutInitDisplayMode(GLUT_SINGLE |GLUT_RGB ); //set the display 	mode 
 glutInitWindowSize(width, height); //set window size 
 glutInitWindowPosition(20, 20); // set window position on screen 
 glutCreateWindow(windowTitle); // open the screen window 	 
 setWindow(0, (float)width, 0, (float)height ); //default window 
 setViewport(0, width, 0, height); //default viewport 
 CP.set(0.0f, 0.0f); //initialize the CP to (0, 0) 
}; 
XÂY DỰNG LỚP CANVAS 
void Canvas::moveTo(float x, float y) 
{ 
 CP.set(x, y); 
} 
void Canvas::lineTo(float x, float y) 
{ 
 glBegin(GL_LINE); 
	glVertex2f((GLfloat) CP.getX(), (GLfloat) CP.getY()); 
	glVertex2f((GLfloat) x, (GLfloat) y); 
 glEnd(); 
 CP.set(x, y); 
 glFlush(); 
} 
void Canvas::setWindow(float l, float r, float b, float t) 
{ 
 glMatrixMode(GL_PROJECTION); 
 glLoadIdentity(); 
 gluOrtho2D((GLdouble)l,(GLdouble)r,(GLdouble)b,(GLdouble)t); 
 window.set(l, r, b, t); 
} 
XÂY DỰNG LỚP CANVAS 
Canvas cvs(640, 480, "try out Canvas"); 
void display() 
{ 
 cvs.clearScreen(); //xóa màn hình 
 cvs.setWindow(-10.0, 10.0, -10.0, 10.0); 
 cvs.setViewport(10, 460, 10, 460); 
 cvs.moveTo(0, -10.0);// vẽ đoạn thẳng 
 cvs.lineTo(0, 10.0); 
 RealRect box(-2.0, 2.0, -1.0, 1.0); //tạo hình chữ nhật 
 box.draw(); 
 ...... 
} 
void main() 
{ 
 cvs.setBackgroundColor(1.0, 1.0, 1.0); 
 cvs.setColor(0.0, 0.0, 0.0); 
 glutDisplayFunc(myDisplay); 
 glutMainLoop(); 
} 
VẼ TƯƠNG ĐỐI 
	 moveTo(first data point); 
	drawMarker(); 
	for(each remaining data point) 
	{ 
	lineTo(the next point); 
	drawMarker(); 
	} 
VẼ TƯƠNG ĐỐI 
void Canvas::moveRel(float dx, float dy) 
{ 
	CP.set(CP.getX() + dx, CP.getY() + dy); 
} 
void Canvas::lineRel(float dx, float dy) 
{	 
 float x =CP.getX() + dx; 
 float y =CP.getY() + dy; 
 lineTo(x, y); 
 CP.set(x, y); 
} 
VẼ TƯƠNG ĐỐI 
void arrow(float f,float h, 
	float t,float w) 
{ 
 cvs.lineRel(-w-t/2, -f); 
 cvs.lineRel(w, 0); 
 cvs.lineRel(0, -h); 
 cvs.lineRel(t, 0); 
 cvs.lineRel(0, h); 
 cvs.lineRel(w, 0); 
 cvs.lineRel(-w-t/2, f); 
} 
f 
h 
w 
w 
t 
CP 
ĐỒ HỌA CON RÙA 
Thêm vào lớp Canvas: 
Biến CD chứa hướng hiện hành 
turnTo(float angle) 
	 CD = angle; 
turn(float angle) 
	 CD += angle; (CCW) 
forward(float dist,int isVisible) 
CD 
CP cũ 
CP mới 
dist 
void Canvas::forward(float dist, int isVisible) { 
	const float RadPerDeg=0.017453393; 
	float x = CP.getX() + dist*cos(RadPerDeg *CD); 
	float y = CP.getY() + dist*sin(RadPerDeg *CD); 
	if( isVisible)	lineTo(x, y); 
	else	moveTo(x, y); 
} 
ĐỒ HỌA CON RÙA 
for(some number of iteration){ 
	 //draw a line in current 
	forward(length, 1); 
 //turn through angle degreee directionturn(angle); 
	 // increment the line length 
	length += increment; 
} 
a) 
b) 
c) 
d) 
Ví dụ: 
Vẽ polyspirals 
(a) 60 0 
(b) 89.5 0 
(c) -144 0 
(d) 170 0 
TẠO HÌNH ẢNH TỪ ĐA GIÁC ĐỀU 
Đa giác đều 
Định nghĩa: đa giác đơn, các cạnh bằng nhau, hai cạnh kề nhau hợp với nhau một góc bằng nhau. 
n: 3 
4 
5 
6 
40 
TẠO HÌNH ẢNH TỪ ĐA GIÁC ĐỀU 
Vẽ đa giác đều 
Pi = ( R cos(2  i / n ), R sin(2  i / n )) với i = 0, 1, ..., n-1 . 
P 1 = (Rcos(ia), Rsin(ia)) 
R 
a 
P 0 
P 2 
x 
y 
void ngon(int n, 
	float cx, float cy, 
 float r, float rotA){ 
if (n < 3) return; 
double angle = rotA*PI/180; 
double angleInc = 2*PI/n; 
cvs.moveTo(r*cos(angle)+cx, 	 	 r*sin(angle)+cy); 
for(int k=0;k<n;k++) 
{ 
 angle += angleInc; 
 cvs.lineTo(r*cos(angle)+cx, 	r*sin(angle)+cy); 
} 
} 
TẠO HÌNH ẢNH TỪ ĐA GIÁC ĐỀU 
Vẽ đa giác bằng đồ họa con rùa 
for(i=0;i<6;i++)	 
{ 
	cvs.forward(L, 1);	 
	cvs.turn(60); 
} 
L 
R 
360/n 
Biến thể của đa giác đều 
a) 
b) 
c) 
VẼ ĐƯỜNG TRÒN VÀ CUNG TRÒN 
Vẽ đường tròn 
void drawCircle(Point2 center, float radius) 
{ 
 const int numVerts = 50; 
 ngon(numVerts,center.getX(),center.getY(),radius,0); 
} 
Cách chỉ định một đường tròn 
Tâm và bán kính 
Tâm và một điểm nằm trên đường tròn 
Ba điểm nằm trên đường tròn 
VẼ ĐƯỜNG TRÒN VÀ CUNG TRÒN 
 Vẽ cung tròn 
void drawArc(Point2 center, float r, 
	float rotA, float sweep) 
{ 
 const int n=30; //number segments 
 float angle = rotA*PI/180; 
 float angleInc = 2*PI/n; 
 float cx=center.getX(), cy=center.getY(); 
 cvs.moveTo(r*cos(angle)+cx, r*sin(angle)+cy); 
 for(int k=1;k<n;k++) 
	{ 
	angle += angleInc; 
	cvs.lineTo(r*cos(angle)+cx, r*sin(angle)+cy); 
 } 
} 
c 
R 
b 
a 
x 
y 
DẠNG BIỂU DIỄN THAM SỐ CỦA ĐƯỜNG CONG 
Dạng ẩn : mô tả đường cong bằng hàm F(x, y). Hàm này cho biết mối quan hệ giữa x và y: điểm (x, y) nằm trên đường cong nếu và chỉ nếu F(x, y) = 0. 
F(x, y) = (y - Ay)(Bx - Ax) - (x - Ax)(By - Ay)	(đthẳng) 
F(x, y) = x 2 + y 2 – R 2 	(đtròn) 
Hàm trong ngoài 
F(x, y) = 0, nếu (x, y) nằm trên đường cong 
F(x, y) > 0, nếu (x, y) nằm ngoài đường cong 
F(x, y) < 0, nếu (x, y) nằm trong đường cong 
Nhược điểm của dạng ẩn 
Đối với hàm đa trị, không thể suy ra y=g(x) từ F(x, y), chẳng hạn từ dạng ẩn của đường tròn, ta có: 
DẠNG BIỂU DIỄN THAM SỐ CỦA ĐƯỜNG CONG 
Dạng biểu diễn tham số 
Ví dụ 1: Đoạn thẳng có hai đầu mút là A và B. Ở thời điểm t = 0, đi qua điểm A; ở thời điểm t = 1 qua điểm B. 
x(t) = Ax + (Bx - Ax)t 
y(t) = Ay + (By - Ay)t 
A (Ax, Ay) 
B (Bx, By) 
@ t = 0 
@ t = 1 
DẠNG BIỂU DIỄN THAM SỐ CỦA ĐƯỜNG CONG 
Dạng biểu diễn tham số 
Ví dụ 2: Đường ellipse có các bán kính là W và H 
 x(t) = Wcos(t) 
 y(t) = Hsin(t) 
với ( 0  t  2  ) 	 
t 
y(t) 
H 
-H 
x 
y 
H 
W 
(x(t), y(t)) 
c 
-c 
t=  
t=  /2 
x(t) 
t 
2  
W 
-W 
2  
 
DẠNG BIỂU DIỄN THAM SỐ CỦA ĐƯỜNG CONG 
Dạng biểu diễn tham số 
dạng ẩn và dạng tham số có cùng biểu diễn một đường cong hay không? 
từ dạng tham số tìm dạng ẩn? 
Ví dụ: đối với hình ellipse 
	x(t) = Wcos(t)  	cos(t) = x/W 
 	y(t) = Hsin(t) 	sin(t) = y/H 
	cos 2 (t) + sin 2 (t) = 1  
DẠNG BIỂU DIỄN THAM SỐ CỦA ĐƯỜNG CONG 
Vẽ đường cong biểu diễn dưới dạng tham số 
t = T 
t = 0 
P(t) = (x(t), y(t)) 
P 1 
P 2 
P m 
a) 
b) 
//draw the curve (x(t), t(t)) using 
//the array t[0], ..., t[n-1] of “sample-times” 
glBegin(GL_LINES); 
	for(int i=0;i<n;i++) 
	 glVertex2f(x(t[i]), y(t[i])); 
glEnd() ; 
DẠNG BIỂU DIỄN THAM SỐ CỦA ĐƯỜNG CONG 
Superellipse 
Dạng ẩn 
Dạng tham số 
	 	n = 2m/(2n+1) 
	n < 1 co vào 
	n > 1 phình ra 
	 n = 1 hình vuông 
DẠNG BIỂU DIỄN THAM SỐ CỦA ĐƯỜNG CONG 
Superhyperbola 
Dạng biểu diễn tham số 
	n = 2m/(2n+1) 
	n < 1 co vào 
	n > 1 phình ra 
	 n = 1 đường thẳng 
DẠNG BIỂU DIỄN THAM SỐ CỦA ĐƯỜNG CONG 
Đường cong trong hệ tọa độ cực 
x 
y 
r 
 
( r ,  ) 
x(t)=r(t)cos(  (t)) 
y(t)=r(t)sin(  (t)) 
x = f(  )cos(  )	 
y = f(  )sin(  ) 
Ví dụ 
cardioid f(  ) = K(1 + cos(  )) rose f(  ) = Kcos(n  ) Archimedean spiral f(  ) = K  
DẠNG BIỂU DIỄN THAM SỐ CỦA ĐƯỜNG CONG 
Đường cong trong hệ tọa độ cực 
Mặt cắt nón (conic section) 
Đường xoắn ốc logarit 
f( ) = Ke a 
a = cot() 
a) 
b) 
a=1 parabola 0 a1hyperbola 
DẠNG BIỂU DIỄN THAM SỐ CỦA ĐƯỜNG CONG 
Đường cong 3D 
P(t) = (x(t), y(t), z(t)) 
Đường helix 
x(t) = cos(t) 
y(t) = sin(t) 
z(t) = bt 
Đường toroidal spiral 
x(t) = (asin(ct) + b)cos(t), 
y(t) = (asin(ct) + b)sin(t), 
z(t) = acos(ct) 

File đính kèm:

  • pptbai_giang_do_hoa_may_tinh_chuong_3_xay_dung_cong_cu_ve_hinh.ppt