M Ở ĐẦU
3.3 Tô màu theo dòng quét (ScanConvert)
Ý tưởng: Sử dụng giao điểm giữa các biên đa giác và đường quét để xác định các
điểm nằm trong đa giác.
Hình 3.3: Tô màu theo dòng quét.
Các bước thuật toán:
- Tìm ymin, ymax lần lượt là giá trị nhỏ nhất, lớn nhất của tập các tung độ của các
đỉnh của đa giác đã cho.
- Ứng với mỗi dòng quét y = k với k thay đổi từyminđến ymax, lặp :
- Tìm tất cả các hoành độ giao điểm của dòng quét y = k với các cạnh của đa giác.
- Sắp xếp các hoành độ giao điểm theo thứ tự tăng dần : x0, x1,..., xn.
- Vẽ các đoạn thẳng trên đường thẳng y = k lần lượt được giới hạn bởi các cặp cách quãng nhau: (x0, x1), (x1, x2), ....
- Hạn chế được số cạnh cần tìm giao điểm ứng với mỗi dòng quét vì ứng với mỗi dòng quét không phải lúc nào cũng giao với các cạnh của đa giác.
- Để tìm giao điểm giữa cạnh đa giác và dòng quét, ta có nhận xét sau:
Trong đó, m là hệ số góc của cạnh.
- Giải quyết trường hợp số giao điểm đi qua đỉnh đơn điệu thì tính số giao điểm là 1 hay đi qua đỉnh cực trị thì tính số giao điểm là 0 (hoặc 2).
Thuật toán ScanConvert
void ScanFill(Point[] Poly) {
int min_y = Poly[0].Y, max_y = Poly[0].Y; int min_x = Poly[0].X, max_x = Poly[0].X; for (int i = 1; i < Poly.Length; i++)
{
if (Poly[i].Y > max_y) max_y = Poly[i].Y; if (Poly[i].Y < min_y) min_y = Poly[i].Y;
if (Poly[i].X > max_x) max_x = Poly[i].X; if (Poly[i].X < min_x) min_x = Poly[i].X; }
Point G = new Point(); Point A, B;
{
List<Point> list = new List<Point>(); for (int i = 0; i < Poly.Length - 1; i++) {
A = Poly[i]; B = Poly[i + 1];
if (Giao(A, B, new Point(min_x, y), new Point(max_x, y), ref G) == true) {
if (G == Poly[j]) {
if (j == 0) {
if ((G.Y > Poly[Poly.Length - 1].Y && G.Y > Poly[1].Y) || (G.Y < Poly[Poly.Length - 1].Y && G.Y < Poly[1].Y))
{ list.Add(G); } } else {
if ((G.Y > Poly[j - 1].Y && G.Y > Poly[j + 1].Y) || (G.Y < Poly[j - 1].Y && G.Y < Poly[j + 1].Y))
{ list.Add(G); } } else { list.Add(G); } } }
A = Poly[Poly.Length - 1]; B = Poly[0];
if (Giao(A, B, new Point(min_x, y), new Point(max_x, y), ref G) == true) {
if (G == Poly[j]) {
if (j == 0) {
if ((G.Y > Poly[Poly.Length - 1].Y && G.Y > Poly[1].Y) || (G.Y < Poly[Poly.Length - 1].Y && G.Y < Poly[1].Y))
{ list.Add(G); } } else {
if ((G.Y > Poly[j - 1].Y && G.Y > Poly[j + 1].Y) || (G.Y < Poly[j - 1].Y && G.Y < Poly[j + 1].Y))
{ list.Add(G); } } else { list.Add(G); } SortList(list); DrawList(list); } }
void SortList(List<Point> list) {
for (int i = 0; i < list.Count - 1; i++) {
for (int j = i + 1; j < list.Count; j++) { if (list[i].X > list[j].X) { Point t = list[i]; list[i] = list[j]; list[j] = t; } } } }
void DrawList(List<Point> list) {
for (int i = 0; i < list.Count - 1; i += 2) {
Line (list[i], list[i + 1]); }
}