Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 39 trang
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
Nội dung
Đồhọamáytính Đề tài 18: Cài đặt thuật toán xén đoạn thẳng Cohen – Sutherland NHẬN XÉT CỦA GVHD SVTH: Nguyễn Văn Long 08266671 + Trần Minh Phong 08220681 Trang Đồhọamáytính Đề tài 18: Cài đặt thuật toán xén đoạn thẳng Cohen – Sutherland SVTH: Nguyễn Văn Long 08266671 + Trần Minh Phong 08220681 Trang Đồhọamáytính Đề tài 18: Cài đặt thuật toán xén đoạn thẳng Cohen – Sutherland SVTH: Nguyễn Văn Long 08266671 + Trần Minh Phong 08220681 Trang Đồhọamáytính Đề tài 18: Cài đặt thuật toán xén đoạn thẳng Cohen – Sutherland MỤC LỤC I Câu 1: Tìm hiểu cài đặt thuật toán xén đoạn thẳng Cohen - Sutherland I.1 Định nghĩa Thao tác loại bỏ phần hình ảnh nằm vùng cho trước gọi xén hình Vùng dùng để xén hình gọi cửa sổ xén (clip window) hay cửa sổ Tùy thuộc vào ứng dụng cụ thể mà cửa sổ xén có dạng đa giác đường cong khép kín Ví dụ: SVTH: Nguyễn Văn Long 08266671 + Trần Minh Phong 08220681 Trang Đồhọamáytính Đề tài 18: Cài đặt thuật tốn xén đoạn thẳng Cohen – Sutherland Trước xén Sau xén Xén đoạn thẳng vào vùng hình chữ nhật R2 Cho miền D⊂Rnvà F hình Rn (F⊂Rn) Ta gọi F∩D hình có từ F cách xén vào D ký hiệu ClipD(F) I.2 Cạnh hình chữ nhật song song với trục tọa độ Ta có: Xmin ≤ x ≤ Xmax D = (x,y) ∈ R | Ymin ≤ y ≤ Ymax Và F đoạn thẳng nối điểm (x1,y1), (x2,y2) nên phương trình F là: x=x1+(x2-x1).t t∈ [0,1] y=y1+(y2-y1).t Do F viết dạng: F ={(x,y)∈ R2|x=x1+(x2-x1).t;y=y1+(y2-y1).t ;0 ≤ t ≤ 1} SVTH: Nguyễn Văn Long 08266671 + Trần Minh Phong 08220681 Trang Đồhọamáytính Đề tài 18: Cài đặt thuật tốn xén đoạn thẳng Cohen – Sutherland Khi đó, giao điểm F D nghiệm bất phương trình theo t: Xmin ≤x=x1+(x2-x1).t ≤ Xmax Ymin ≤ y=y1+(y2-y1).t ≤ Ymax 0≤t≤1 Gọi N tập nghiệm hệ phương trình trên: Nếu N = Ø ClipD(F)= Ø Nếu N ≠ Ø N =[t1,t2] (t1≤t2) Gọi P, Q giao điểm xác định bởi: Px = x1+(x2-x1).t1 Py = y1+(y2-y1).t1 Qx = x1+(x2-x1).t1 Qy = y1+(y2-y1).t1 Lúc ta có được: ClipD(F) = PQ Ví dụ: Xét toán xén đoạn thẳng cho hai điểm P1(x1,y1) P2(x2,y2) vào cửa sổ hình chữ nhật SVTH: Nguyễn Văn Long 08266671 + Trần Minh Phong 08220681 Trang Đồhọamáytính Đề tài 18: Cài đặt thuật toán xén đoạn thẳng Cohen – Sutherland Trước xén Sau xén Phương pháp chung thuật toán xén đoạn thẳng: − Loại bỏ phép tốn tìm giao điểm đoạn thẳng với biên cửa sổ cách nhanh đoạn thẳng đặc biệt nằm hoàn toàn hoàn toàn bên cửa sổ (P1P2 P3P4) − Các đoạn thẳng mà có hai điểm nằm hồn tồn cửa sổ đoạn thẳng nằm cửa sổ (P1P2) − Các đoạn thẳng mà có hai điểm nằm phía cửa sổ ln nằm cửa sổ bị sau xén (P3P4) − Các đoạn thẳng có khả cắt cửa sổ (P5P6 P7P8) cần rút gọn việc tìm giao điểm với biên cửa sổ không cần thiết để xác định phần giao có đoạn thẳng cửa sổ SVTH: Nguyễn Văn Long 08266671 + Trần Minh Phong 08220681 Trang Đồhọamáytính Đề tài 18: Cài đặt thuật toán xén đoạn thẳng Cohen – Sutherland I.3 Thuật toán Cohen – Sutherland Mã vùng số bit nhị phân gán cho vùng để mơ tả vị trí tương đối vùng so với cửa sổ Kéo dài biên W, chia mặt phẳng thành vùng, vùng gán mã nhị phân 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 cửa sổ Bit 4: Quy định vùng nằm bên cửa sổ Xét điểm P∈R2: Xét đoạn thẳng AB có trường hợp sau: SVTH: Nguyễn Văn Long 08266671 + Trần Minh Phong 08220681 Trang Đồhọamáytính Đề tài 18: Cài đặt thuật toán xén đoạn thẳng Cohen – Sutherland Nếu Mã(A) = Mã(B) = 0000 AB ∈ D => ClipD(F) = AB Nếu Mã(A) AND Mã(B) ≠ 0000 đoạn AB nằm hồn tồn bên ngồi hình chữ nhật => ClipD(F) = Ø − Nếu (Mã(A) AND Mã(B) = 0000) (Mã(A) ≠ 0000 Mã(B) ≠ 0000) thì: Giả sử Mã(A) ≠ 0000 A nằm ngồi hình chữ nhật + Nếu Aleft = 1: thay A điểm nằm cạnh AB cắt cạnh trái nối dài hình chữ nhật + Nếu Aright = 1: thay A điểm nằm cạnh AB cắt cạnh phải nối dài hình chữ nhật + Nếu Abelow= 1: thay A điểm nằm cạnh AB cắt cạnh nối dài hình chữ nhật + Nếu Aabove = 1: thay A điểm nằm cạnh AB cắt cạnh nối dài hình chữ nhật Lưu đồ thuật tốn: − − SVTH: Nguyễn Văn Long 08266671 + Trần Minh Phong 08220681 Trang Đồhọamáytính I.4 I.4.1 Đề tài 18: Cài đặt thuật toán xén đoạn thẳng Cohen – Sutherland Ví dụ minh họa Ví dụ 1: SVTH: Nguyễn Văn Long 08266671 + Trần Minh Phong 08220681 Trang 10 Đồhọamáytính Đề tài 18: Cài đặt thuật tốn xén đoạn thẳng Cohen – Sutherland { p[0] = XenRight(right, a, b); return XenDoanThang(p[0], p[1], left, right, top, bottom); } if (c1[1] == 1) { p[0] = XenBottom(bottom, a, b); return XenDoanThang(p[0], p[1], left, right, top, bottom); } if (c1[0] == 1) { p[0] = XenTop(top, a, b); return XenDoanThang(p[0], p[1], left, right, top, bottom); } } else { HoanVi(p[0], p[1]); return XenDoanThang(p[0], p[1], left, right, top, bottom); } } return null; } else { return p; } } #endregion #region Vẽ cửa sổ xén public static void Windows(Graphics g, float left, float right, float top, float bottom, int h, int w, Color c) { Point2D.MyLine(g, h, w, new Point2D(left, bottom), new Point2D(left, top), c); Point2D.MyLine(g, h, w, new Point2D(left, bottom), new Point2D(right, bottom), c); Point2D.MyLine(g, h, w, new Point2D(left, top), new Point2D(right, top), c); Point2D.MyLine(g, h, w, new Point2D(right, top), new Point2D(right, bottom), c); SVTH: Nguyễn Văn Long 08266671 + Trần Minh Phong 08220681 Trang 25 Đồhọamáytính Đề tài 18: Cài đặt thuật tốn xén đoạn thẳng Cohen – Sutherland } #endregion #region Di chuyển cửa sổ xén theo độ rời dx, dy public static void DiChuyenCuaSoXen(float dx, float dy,ref float left,ref float right,ref float top,ref float bottom, bool isLeft, bool isRight, bool isTop, bool isBottom) { if (isLeft) { left -= dx; right -= dx; } else if (isRight) { left += dx; right += dx; } else if (isTop) { top += dy; bottom += dy; } else if (isBottom) { top -= dy; bottom -= dy; } } #endregion #region Thay đổi cửa sổ xén theo dx,dy public static void ThayDoiCuaSoXen(float dx, float dy, ref float left, ref float right, ref float top, ref float bottom, bool isLeft, bool isRight, bool isTop, bool isBottom) { if (isLeft && isRight && isTop && isBottom) SVTH: Nguyễn Văn Long 08266671 + Trần Minh Phong 08220681 Trang 26 Đồhọamáytính Đề tài 18: Cài đặt thuật toán xén đoạn thẳng Cohen – Sutherland { left -= dx; right += dx; top += dy; bottom -= dy; } else { if (isLeft) { left -= dx; } else if (isRight) { right += dx; } else if (isTop) { top += dy; } else if (isBottom) { bottom -= dy; } } } #endregion } } II.6.2 Source code tranh rừng thông using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; SVTH: Nguyễn Văn Long 08266671 + Trần Minh Phong 08220681 Trang 27 Đồhọamáytính Đề tài 18: Cài đặt thuật toán xén đoạn thẳng Cohen – Sutherland using System.Collections; namespace De18 { public partial class frmCanhRungThong : Form { #region Member variables private Graphics _g; private int _h, _w; private float _letf, _right, _top, _bottom; private SortedList _vert = new SortedList(); private SortedList _vert2 = new SortedList(); private SortedList _edge = new SortedList(); private SortedList _edge2 = new SortedList(); private int _indexVert = 0, _indexVert2 = 0; private int _indexEdge = 0, _indexEdge2 = 0; private float _dx, _dy; private SortedList _vert3 = new SortedList(); private SortedList _vert32 = new SortedList(); private SortedList _edge3 = new SortedList(); private SortedList _edge32 = new SortedList(); private int _indexVert3 = 0, _indexVert32 = 0; private int _indexEdge3 = 0, _indexEdge32 = 0; #endregion #region Constructors public frmCanhRungThong() { InitializeComponent(); } #endregion #region Private Methods #region Thêm điểm private void ThemDiem(Point2D p) SVTH: Nguyễn Văn Long 08266671 + Trần Minh Phong 08220681 Trang 28 Đồhọamáytính Đề tài 18: Cài đặt thuật toán xén đoạn thẳng Cohen – Sutherland { _vert.Add(_indexVert, p); _indexVert++; } private void ThemDiemXen(Point2D p) { _vert2.Add(_indexVert2, p); _indexVert2++; } private void ThemDiem3(Point2D p) { _vert3.Add(_indexVert3, p); _indexVert3++; } private void ThemDiemXen3(Point2D p) { _vert32.Add(_indexVert32, p); _indexVert32++; } #endregion #region Thêm cạnh private void ThemCanh(int indexVert1, int indexVert2) { _edge.Add(_indexEdge, indexVert1); _indexEdge++; _edge.Add(_indexEdge, indexVert2); _indexEdge++; } private void ThemCanhXen(int indexVert1, int indexVert2) { _edge2.Add(_indexEdge2, indexVert1); _indexEdge2++; _edge2.Add(_indexEdge2, indexVert2); _indexEdge2++; SVTH: Nguyễn Văn Long 08266671 + Trần Minh Phong 08220681 Trang 29 Đồhọamáytính Đề tài 18: Cài đặt thuật toán xén đoạn thẳng Cohen – Sutherland } private void ThemCanh3(int indexVert1, int indexVert2) { _edge3.Add(_indexEdge3, indexVert1); _indexEdge3++; _edge3.Add(_indexEdge3, indexVert2); _indexEdge3++; } private void ThemCanhXen3(int indexVert1, int indexVert2) { _edge32.Add(_indexEdge32, indexVert1); _indexEdge32++; _edge32.Add(_indexEdge32, indexVert2); _indexEdge32++; } #endregion #region Tạo private void TaoNgoiSao(float cx, float cy, float r) { int soDinh = 5; double a = * Math.PI / soDinh; Point2D[] p = new Point2D[soDinh]; //Xác định tọa độ đỉ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)); } for (int i = 0; i < p.Length - 2; i++) { ThemDiem3(p[i]); ThemDiem3(p[i + 2]); ThemCanh3(_indexVert3 - 1, _indexVert3); SVTH: Nguyễn Văn Long 08266671 + Trần Minh Phong 08220681 Trang 30 Đồhọamáytính Đề tài 18: Cài đặt thuật tốn xén đoạn thẳng Cohen – Sutherland } for (int i = 0; i < p.Length - 3; i++) { ThemDiem3(p[i]); ThemDiem3(p[i + 3]); ThemCanh3(_indexVert3 - 1, _indexVert3); } } private void TaoNgoiSao() { TaoNgoiSao(50, 400, 9); TaoNgoiSao(30, 450, 7); TaoNgoiSao(100, 450, 12); TaoNgoiSao(150, 420, 8); TaoNgoiSao(120, 380, 6); TaoNgoiSao(125, 350, 4); TaoNgoiSao(180, 450, 8); TaoNgoiSao(230, 420, 12); TaoNgoiSao(330, 460, 8); TaoNgoiSao(500, 390, 6); TaoNgoiSao(520, 430, 11); TaoNgoiSao(650, 430, 5); TaoNgoiSao(700, 450, 12); TaoNgoiSao(780, 420, 10); TaoNgoiSao(890, 450, 6); TaoNgoiSao(910, 420, 4); } #endregion #region Tạo mặt trăng private void TaoMatTrang(float cx, float cy, float r, int n) { double a = * Math.PI / n; Point2D[] p = new Point2D[n]; //Xác định tọa độ đỉnh for (int i = 0; i < n; i++) { SVTH: Nguyễn Văn Long 08266671 + Trần Minh Phong 08220681 Trang 31 Đồhọamáytính Đề tài 18: Cài đặt thuật tốn xén đoạn thẳng Cohen – Sutherland p[i] = new Point2D(cx + r * (float)Math.Cos(a * i), cy + r * (float)Math.Sin(a * i)); } for (int i = 0; i < n; i++) { ThemDiem3(p[i]); ThemDiem3(p[n - i - 1]); ThemCanh3(_indexVert3 - 1, _indexVert3); } } #endregion #region Tạo cành thông private void TaoCanhThong(float ngx, float ngy, int n, float y) { Point2D p; Point2D ngon = new Point2D(ngx, ngy); for (int i = 0; i