You are on page 1of 3

Bài Thực Hành Số 3:

Bổ sung tính năng cho SampleCAD


Nội dung:
- Cho phép người dùng chọn đối tượng hình học mong muốn.
- Cho phép người dùng di chuyển (Translate) đối tượng bằng Keyboard và Mouse theo đường thẳng hay
mặt phẳng trong không gian 3 chiều.
- Cho phép người dùng co hay mở rộng (Scale) một đối tượng mong muốn.
- Sử dụng phím để cho phép các đối tượng chuyển động quay: quanh trục cục bộ Ox, Oy, Oz

Hướng dẫn:
I. Chọn đối tượng (Picking)
Bổ sung thêm button SELECT trên thanh toolbar để thực hiện chọn lựa đối tượng. Sử dụng giải
thuật ở phần 3.8.1 trong sách Interactive Computer Graphics.
II. Di chuyển (Moving)
Sử dụng thêm biến m_center trong class CGeometricObject thể hiện tâm của đối tượng. Khi đối
tượng thay đổi vị trí ta cập nhật lại tọa độ của biến này.

CPoint3D m_center; //center of mass: the object's center


1. Sử dụng Keyboard
Sử dụng các nút trên bàn phím để thực hiện tăng giảm tọa độ x, y, z của đối tượng.
2. Sử dụng Mouse

Bước 1: Chuyển tọa độ màn hình sang tọa độ OpenGL

a. Tọa độ viewport
Chúng ta cần lấy thông tin viewport hiện tại. Thông tin mà chúng ta cần là vị trí (x, y) của
viewport và kích thước (width, height) của viewport).
Một khi chúng ta lấy được những thông tin này bằng cách sử dụng hàm
glGetIntegerv(GL_VIEWPORT, viewport), biến viewport sẽ lưu giữ thông tin sau:
viewport[0]=x
viewport[1]=y
viewport[2]=width
viewport[3]=height

GLint viewport[4]; // Where The Viewport Values Will Be Stored


glGetIntegerv(GL_VIEWPORT, viewport); // Retrieves The Viewport Values (X, Y,
Width, Height)

b. Ma trận ModelView
Sau khi có được thông tin viewport, chúng ta có thể lấy được thông tin về ModelView. Ma trận
ModelView giúp xác định các đỉnh của OpenGL primitives được biến đổi như thế nào trong hệ tọa độ mắt
nhìn.
GLdouble modelview[16]; // Where The 16 Doubles Of The Modelview Matrix Are To Be
Stored
glGetDoublev(GL_MODELVIEW_MATRIX, modelview); // Retrieve The Modelview Matrix

c. Ma trận chiếu
Sau đó chúng ta cần lấy thông tin ma trận chiếu. Ma trận chiếu biến đổi đỉnh trong hệ tọa độ mắt
nhìn đến hệ tọa độ clipping.

GLdouble projection[16]; // Where The 16 Doubles Of The Projection Matrix Are To Be


Stored
glGetDoublev(GL_PROJECTION_MATRIX, projection); // Retrieve The Projection Matrix

d. Hệ tọa độ cửa sổ màn hình


GLfloat winX, winY, winZ; // Holds Our X, Y and Z Coordinates

winX = (float)mouse.x; // Holds The Mouse X Coordinate


winY = (float)mouse.y; // Holds The Mouse Y Coordinate

Chú ý rằng hệ tọa độ windows bắt đầu vị trí (0, 0) nằm ở góc trên bên trái trong khi đó hệ tọa độ
OpenGL bắt đầu ở góc dưới bên trái. Do đó, ta phải chuyển sang tọa độ OpenGL bằng cách sau đây:

winY = (float)viewport[3] - winY; // Subtract The Current Mouse Y Coordinate From The
Screen Height.

Đến đây chúng ta vẫn còn thiếu tọa độ z. Đây là cách dùng để lấy tọa độ này:

glReadPixels(winX, winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);

e. Phục hồi tọa độ OpenGL


Tất cả những việc còn lại là tính toán tọa độ OpenGL cuối cùng

GLdouble posX, posY, posZ; // Hold The Final Values


gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);

Toàn bộ đoạn mã dùng để chuyển từ hệ tọa độ cửa sổ màn hình (windows) sang hệ tọa độ
OpenGL như sau:

CVector3 GetOGLPos(int x, int y)


{
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
GLfloat winX, winY, winZ;
GLdouble posX, posY, posZ;

glGetDoublev( GL_MODELVIEW_MATRIX, modelview );


glGetDoublev( GL_PROJECTION_MATRIX, projection );
glGetIntegerv( GL_VIEWPORT, viewport );

winX = (float)x;
winY = (float)viewport[3] - (float)y;
glReadPixels( x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );

gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY,


&posZ);

return CVector3(posX, posY, posZ);


}
Bước 2 : Tìm giao điểm của tia (từ mắt nhìn đến vị trị mouse) với mặt phẳng mà đối tượng dịch
chuyển.

Bước 3 : Di chuyển đối tượng song song với đường thẳng nối giao điểm (tìm được ở bước số 2)
và vị trí mới.

III. Tăng giảm kích thước đối tượng (Scale)

Sử dụng thêm biến m_scale (véc tơ 3 chiều) trong class CGeometricObject để thể hiện kích
thước của đối tượng.

CFactor3D m_scale; //the scale of the object

Sử dụng phím để tăng hoặc giảm kích thước của đối tượng theo các trục Ox, Oy, Oz.

IV. Quay (Rotate)


Sử dụng Quaternion để thực hiện các phép quay quanh trục cục bộ (sử dụng phím)

CQuaternion m_rotObject;

You might also like