1. Trang chủ
  2. » Công Nghệ Thông Tin

Lập trình đồ họa máy tính

39 325 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 39
Dung lượng 532,44 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Xén đoạn thẳng vào vùng hình chữ nhật của R 2 Cho một miền D⊂Rnvà F là một hình trong Rn F⊂Rn.. Trước khi xén Sau khi xénPhương pháp chung của các thuật toán xén đoạn thẳng: − Loại bỏ ph

Trang 1

NHẬN XÉT CỦA GVHD

Trang 3

Trang 5

Trước khi xén Sau khi xén

I.2. Xén đoạn thẳng vào vùng hình chữ nhật của R 2

Cho một miền D⊂Rnvà F là một hình trong Rn (F⊂Rn) Ta gọi F∩D là hình có từ F

bằng cách xén vào trong D và ký hiệu là Clip D (F).

Cạnh của hình chữ nhật song song với các trục tọa độ

Trang 6

Khi đó, giao điểm của F và D chính là nghiệm của bất phương trình theo t:

Xmin ≤x=x1+(x2-x1).t ≤ XmaxYmin ≤ y=y1+(y2-y1).t ≤ Ymax

0 ≤ t ≤ 1

Gọi N là tập nghiệm của hệ phương trình trên:

Nếu N = Ø thì ClipD(F)= ØNếu N ≠ Ø thì N =[t1,t2] (t1≤t2)Gọi P, Q là 2 giao điểm xác định bởi:

Px = x1+(x2-x1).t1 Qx = x1+(x2-x1).t1

Py = y1+(y2-y1).t1 Qy = y1+(y2-y1).t1Lúc đó ta có được: ClipD(F) = PQ

Ví dụ: Xét bài toán xén đoạn thẳng được cho bởi hai điểm P1(x1,y1) và P2(x2,y2) vào cửa

sổ hình chữ nhật

Trang 7

Trước khi xén Sau khi xén

Phương pháp chung của các thuật toán xén đoạn thẳng:

− Loại bỏ phép toán tìm giao điểm giữa đoạn thẳng với biên của cửa sổ một cách nhanh nhất đối với các đoạn thẳng đặc biệt như nằm hoàn toàn trong hoặc hoàn toàn bên ngoài cửa sổ (P1P2 và P3P4)

− Các đoạn thẳng mà có cả hai điểm nằm hoàn toàn trong cửa sổ thì cả đoạn thẳng nằm trong cửa sổ (P1P2)

− Các đoạn thẳng mà có hai điểm nằm về cùng một phía của cửa sổ thì luôn nằm ngoài cửa sổ và sẽ bị mất sau khi xén (P3P4)

− Các đoạn thẳng có khả năng cắt cửa sổ (P5P6 và P7P8) cần rút gọn việc tìm giao điểm với những biên cửa sổ không cần thiết để xác định phần giao nếu có của đoạn thẳng và cửa sổ

Trang 8

vùng đó so với cửa sổ

Kéo dài các biên của W, chia mặt phẳng thành 9 vùng, mỗi vùng gán một mã nhị phân

4 bit

Bit 1: Quy định vùng nằm bên trái cửa sổ

Bit 2: Quy định vùng nằm bên phải cửa sổ

Bit 3: Quy định vùng nằm bên dưới cửa sổ

Bit 4: Quy định vùng nằm bên trên cửa sổ

Xét điểm P∈R2:

Xét đoạn thẳng AB sẽ có các trường hợp sau:

Trang 9

− Nếu Mã(A) = Mã(B) = 0000 thì AB ∈ D => ClipD(F) = AB.

− Nếu Mã(A) AND Mã(B) ≠ 0000 thì đoạn AB nằm hoàn toàn bên ngoài hìnhchữ nhật => ClipD(F) = Ø

− Nếu (Mã(A) AND Mã(B) = 0000) và (Mã(A) ≠ 0000 hoặc Mã(B) ≠ 0000) thì: Giả sử Mã(A) ≠ 0000  A nằm ngoài hình chữ nhật

+ Nếu Aleft = 1: thay A bởi điểm nằm trên cạnh AB và cắt cạnh trái nối dài của hình chữ nhật

+ Nếu Aright = 1: thay A bởi điểm nằm trên cạnh AB và cắt cạnh phải nối dài của hình chữ nhật

+ Nếu Abelow= 1: thay A bởi điểm nằm trên cạnh AB và cắt cạnh dưới nối dài của hình chữ nhật

+ Nếu Aabove = 1: thay A bởi điểm nằm trên cạnh AB và cắt cạnh trên nối dài của hình chữ nhật

Lưu đồ thuật toán:

Trang 10

I.4. Ví dụ minh họa

I.4.1. Ví dụ 1:

Trang 11

I.4.2. Ví dụ 2:

Trang 12

I.4.3. Ví dụ 3:

Trang 13

II. Câu 2: Vẽ bức tranh rừng thông

Trang 14

Nhiệm vụ đề tài là sử dụng các đoạn thẳng để vẽ một bức tranh rừng thông,

và sử dụng thuật toán xén đoạn thẳng Cohen – Sutherland để tạo hiệu ứng như nhìn rừng thông qua cửa ô tô đang chuyển động

II.2. Phân tích đặc tả các chức năng cần có của chương trình

Vẽ toàn cảnh bức tranh rừng thông

Xén rừng thông vào cửa sổ

Mở rộng cửa sổ xén sang bên trái

Mở rộng cửa sổ xén sang bên phải

Mở rộng cửa sổ xén sang lên trên

Mở rộng cửa sổ xén sang xuống dưới

Mở rộng cửa sổ xén theo các phương

Thu nhỏ cửa sổ xén từ bên trái

Thu nhỏ cửa sổ xén từ bên phải

Thu nhỏ cửa sổ xén từ bên trên

Thu nhỏ cửa sổ xén từ bên dưới

Thu nhỏ cửa sổ xén theo các phương

Di chuyển cửa sổ xén sang trái

Di chuyển cửa sổ xén sang phải

Di chuyển cửa sổ xén lên trên

Di chuyển cửa sổ xén xuống dưới

II.3. Tổ chức dữ liệu của chương trình: kiểu biến lưu thông tin hình vẽ, các

biến được khai báo và sử dụng.

private Graphics _g;

privateint _h, _w;

Trang 15

privatefloat _letf, _right, _top, _bottom;

private SortedList<int, Point2D> _vert = new SortedList<int, Point2D>();

private SortedList<int, Point2D> _vert2 = new SortedList<int, Point2D>();

private SortedList<int, int> _edge = new SortedList<int, int>();

private SortedList<int, int> _edge2 = new SortedList<int, int>();

privateint _indexVert = 0, _indexVert2 = 0;

privateint _indexEdge = 0, _indexEdge2 = 0;

privatefloat _dx, _dy;

Thông tin hình vẽ được lưu thông qua 2 danh sách, danh sách điểm và danh sách cạnh Kiểu dữ liệu được dùng là SortedList<int, Point2D> và SortedList<int, int>

II.4. Trình bày cách thức xây dựng tọa độ và khởi tạo biến chứa thông tin hình

vẽ.

Thông tin hình vẽ được lưu trữ bởi 2 danh sách cạnh (edge) và danh sách điểm (vert)

Danh sách điểm được lưu theo dạng key/value

Danh sách cạnh được lưu dưới dạng 2 điểm đầu và cuối của cạnh sẽ đc lưu ở 2

vị trí liền kề, giá trị là khóa trong danh sách điểm của 2 điểm đó

Danh sách được lưu bởi các SortedList nên số phần tử sẽ không bị hạn chế mà

có thể lưu với số phần tử chưa xác định

II.5. Các hình ảnh kết quả thực thi chương trình

Trang 19

II.6. Listing source code

II.6.1. Source code class Point2D

Trang 20

public Point2D(float x, float y)

#region Xác định vị trí của điểm p

publicstaticbyte[] ViTriDiem(Point2D p, float left, float right, float top, float

bottom)

{

Trang 21

byte[] c = newbyte[4];

#region Phép toán quan hệ And

privatestaticbyte[] And(byte[] c1, byte[] c2)

{

byte[] c = newbyte[4];

for (int i = 0; i < c.Length; i++)

Trang 22

#region Tính hệ số a của đường thẳng y = a*x + b đi qua 2 điểm p0 và p1

publicstaticfloat HeSo_a(Point2D p0, Point2D p1)

#region Tính hệ số b của đường thẳng y = a*x + b đi qua 2 điểm p0 và p1

publicstaticfloat HeSo_b(Point2D p0, Point2D p1)

{

return -p0.X * (p1.Y - p0.Y) / (p1.X - p0.X) + p0.Y;

}

#endregion

#region Tính giá trị y theo phương trình y = a*x + b

privatestaticfloat GiaTri_Y(float a, float b, float x)

{

return a * x + b;

}

#endregion

#region Tính giá trị x theo phương trình x = (y-b)/a

privatestaticfloat GiaTri_X(float a, float b, float y)

Trang 23

float x = GiaTri_X(a, b, y);

returnnew Point2D(x, y);

}

#endregion

#region Xén bottom

Trang 24

{

float y = bottom;

float x = GiaTri_X(a, b, y);

returnnew Point2D(x, y);

}

#endregion

#region Xén đoạn thẳng p0 p1

publicstatic Point2D[] XenDoanThang(Point2D p0, Point2D p1, float left, float

right, float top, float bottom)

{

float a = HeSo_a(p0, p1);

float b = HeSo_b(p0, p1);

Point2D[] p = new Point2D[2];

p[0] = new Point2D(p0.X, p0.Y);

p[1] = new Point2D(p1.X, p1.Y);

byte[] c = newbyte[4];

byte[] c1 = newbyte[4];

byte[] c2 = newbyte[4];

c[0] = c[1] = c[2] = c[3] = 0;

c1 = ViTriDiem(p[0], left, right, top, bottom);

c2 = ViTriDiem(p[1], left, right, top, bottom);

Trang 25

publicstaticvoid Windows(Graphics g, float left, float right, float top, float

bottom, int h, int w, Color c)

Trang 26

#endregion

#region Di chuyển cửa sổ xén theo độ rời dx, dy

publicstaticvoid DiChuyenCuaSoXen(float dx, float dy,reffloat left,reffloat

right,reffloat top,reffloat bottom,

bool isLeft, bool isRight, bool isTop, bool

#region Thay đổi cửa sổ xén theo dx,dy

publicstaticvoid ThayDoiCuaSoXen(float dx, float dy, reffloat left, reffloat

right, reffloat top, reffloat bottom,

bool isLeft, bool isRight, bool isTop, bool

isBottom)

{

if (isLeft && isRight && isTop && isBottom)

Trang 28

privatefloat _letf, _right, _top, _bottom;

private SortedList<int, Point2D> _vert = new SortedList<int, Point2D>();

private SortedList<int, Point2D> _vert2 = new SortedList<int, Point2D>(); private SortedList<int, int> _edge = new SortedList<int, int>();

private SortedList<int, int> _edge2 = new SortedList<int, int>();

privateint _indexVert = 0, _indexVert2 = 0;

privateint _indexEdge = 0, _indexEdge2 = 0;

privatefloat _dx, _dy;

private SortedList<int, Point2D> _vert3 = new SortedList<int, Point2D>(); private SortedList<int, Point2D> _vert32 = new SortedList<int, Point2D>(); private SortedList<int, int> _edge3 = new SortedList<int, int>();

private SortedList<int, int> _edge32 = new SortedList<int, int>();

privateint _indexVert3 = 0, _indexVert32 = 0;

privateint _indexEdge3 = 0, _indexEdge32 = 0;

#region Private Methods

#region Thêm điểm

privatevoid ThemDiem(Point2D p)

Trang 30

privatevoid ThemCanh3(int indexVert1, int indexVert2)

#region Tạo ngôi sao

privatevoid TaoNgoiSao(float cx, float cy, float r)

{

int soDinh = 5;

double a = 2 * Math.PI / soDinh;

Point2D[] p = new Point2D[soDinh];

//Xác định tọa độ các đỉnh

for (int i = 0; i < soDinh; i++)

{

p[i] = new Point2D(cx + r * (float)Math.Cos(a * i), cy + r *

(float)Math.Sin(a * i));

Trang 31

#region Tạo mặt trăng

privatevoid TaoMatTrang(float cx, float cy, float r, int n)

Trang 32

#region Tạo cành thông

privatevoid TaoCanhThong(float ngx, float ngy, int n, float y)

{

Point2D p;

Point2D ngon = new Point2D(ngx, ngy);

for (int i = 0; i <= n * 2; i++)

#region Tạo thân cây thông

privatevoid TaoThanCayThong(float x1, float y1, int n,float doRongThanCay) {

Trang 33

#region Tạo cây cỏ

privatevoid TaoCayCo(float x1, float y1, int n)

{

Point2D goc, p;

for (int i = 0; i < n; i++)

{

#region Cây cỏ bên trái cây thông

goc = new Point2D(x1 - 15 - i * 10, y1 + i * 5);

#region Cây cỏ bên phải cây thông

goc = new Point2D(x1 + 20 - i * 10, y1 + i * 5 - 5);

ThemDiem(goc);

p = new Point2D(x1 + 20 - i * 10, y1 + 35 + i * 5 - 5);

ThemDiem(p);

Trang 35

}

#endregion

#region Tạo cây thông + cây cỏ

privatevoid TaoCayThong(float ngx, float ngy, int n, float y,float

#region Tạo rừng thông

privatevoid TaoRungThong()

Trang 37

privatevoid XenRungThongVaoCuaSo()

Point2D.Windows(_g, _letf, _right, _top, _bottom, _h, _w, Color.Red);

Point2D[] p = new Point2D[2];

for (int i = 0; i < _edge.Count - 3; i = i + 2)

VeHinh(_g, _h, _w, _vert32, _edge32, Color.Azure);

VeHinh(_g, _h, _w, _vert2, _edge2,Color.Green);

Point2D.Windows(_g, _letf, _right, _top, _bottom, _h, _w, Color.Red);

Trang 38

#endregion

#region Tạo con đường

privatevoid TaoLeDuong(float x1, float y1, float x2, float y2)

#region Tạo vạch đường

privatevoid TaoVachDuong(float x1, float y1, float x2, float y2, float x3, float

y3, float x4, float y4, int n)

{

Point2D[] p = new Point2D[2];

for (int i = 0; i < n; i++)

{

p[0] = new Point2D(x1 + (x2 - x1) / n * i, y1 + (y2 - y1) / n * i);

p[1] = new Point2D(x3 + (x4 - x3) / n * i, y3 - (y4 - y3) / n * i);

Trang 39

privatevoid TaoConDuong()

Tài liệu tham khảo

1. Giáo trình đồ họa máy tính - ĐHKHTN

2. Giáo trình lý thuyết đồ họa - ĐH Huế

3. Slide đồ họa – Nguyễn Thị Minh Hiếu

Ngày đăng: 25/10/2018, 18:29

TỪ KHÓA LIÊN QUAN

w