Tải bản đầy đủ (.pdf) (5 trang)

Đồ họa máy tính : CÁC ĐỐI TƯỢNG ĐỒ HỌA CƠ SỞ part 7 pot

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (435.75 KB, 5 trang )

aIntersectPt.NumPt
=
0
;
for(int
i
=
FirstId
;
i
<=
LastId
;
i
++)
{
if(
EdgeList.aEdge
[
i
]
.DeltaY
>
0
)
{
aIntersectPt.xPt
[
aIntersectPt.NumPt
]
=


EdgeList.aEdge
[
i
]
.xIntersect
;
aIntersectPt.NumPt
++;
}
}
SortOnX
(
aIntersectPt
);
} //FindXIntersection
#define
Round
(
x
)

int(
x
+
0.5
)
void

FillLine(
XINTERSECT aIntersectPt

,

int
yScan
)
{
for(int
i
=
0
;
i
<
aIntersectPt.NumPt
;
i
+=
2
)
line
(
Round
(
aIntersectPt.xPt
[
i
]),
yScan
,
Round

(
aIntersectPt.xPt
[
i
+
1
]),
yScan
);
} // FillLine
void

UpdateEdgeList(
EDGELIST
&
EdgeList
,int
FirstId
,int
LastId
)
{
for(int
i
=
FirstId
;
i
<=
LastId

;
i
++)
{
if(
EdgeList.aEdge
[
i
]
.DeltaY
>
0
)
{
EdgeList.aEdge
[
i
]
.DeltaY
;
EdgeList.aEdge
[
i
]
.xIntersect
+=
EdgeList.aEdge
[
i
]

.dxPerScan
;
}
}
} //FillLine
void ScanLineFill(
POLYGON P
)
{
EDGELIST EdgeList
;
XINTERSECT aIntersectPt
;
int
TopScan
,
BottomScan, FirstId
,
LastId
;
MakeSortedEdge
(
P
,
EdgeList
,
TopScan
,
BottomScan
);

FirstId
=
LastId
=
0
;
for(int
i
=
BottomScan
;
i
<=
TopScan
;
i
++)
{
//
Cap nhat lai danh sach cac canh
active
-
tuc la cac canh cat dong quet i
UpdateActiveEdgeList
(
EdgeList
,
i
,
FirstId

,
LastId
);
//
Tim cac hoanh do giao diem cua
dong quet voi cac canh cua da giac va
sap xep lai cac hoanh do giao diem
truc tiep tren EdgeList
FindXIntersection
(
EdgeList
,
aIntersectPt
,
FirstId
,
LastId
);
FillLine
(
aIntersectPt
,
i
);
UpdateEdgeList
(
EdgeList
,
FirstId
,

LastId
);
}
} //ScanLineFill
Lưu đồ thuật toán tô màu theo dòng quét
















3.2. Thuật toán tô màu dựa theo
đường biên
Khác với thuật toán tô màu dựa theo dòng quét, đường biên của vùng tô được xác định bởi tập các
đỉnh của một đa giác, đường biên trong thuật toán được mô tả bằng một giá trị duy nhất đó là màu
của tất cả các điểm thuộc về đường biên.
Bắt đầu từ điểm nằm bên trong vùng tô, ta sẽ kiểm tra các điểm lân cận của nó đã được tô màu hay
có phải là điểm biên hay không, nếu không phải là điểm đã tô và không phải là điểm biên ta sẽ tô
màu nó. Quá trình này được lặp lại cho tới khi nào không còn tô được điểm nào nữa thì dừng.
Bằng cách này, toàn bộ các điểm thuộc vùng tô được kiểm tra và sẽ được tô hết.

Hình 2.24
– Thuật toán tô màu dựa theo đường biên
Có hai quan điểm về cách tô này, đó là dùng bốn điểm lân cận hay tám điểm lân cận đối với điểm
đang xét được tô bằng màu trắng (xem hình 2.25).
Hình 2.25
– 4 điểm lân cận (a) và 8 điểm lân cận (b)
Đoạn chương trình sau minh họa cài đặt thuật toán tô màu dựa theo đường biên sử dụng phương
pháp tô 4 điểm lân cận.
Cài đặt minh họa thuật toán tô màu dựa theo đường biên
void

BoundaryFill(int
x
,

int
y
,

int
FillColor
,

int
BoundaryColor
)
{
int
CurrentColor
;

CurrentColor
=
getpixel
(
x
,
y
);
if((
CurrentColor
!=
BoundaryColor
)&&
CurrentColor
!=
FillColor
))
{
putpixel
(
x
,
y
,
FillColor
);
BoundaryFill
(
x
-

1
,
y
,
FillColor
,
BoundaryColor
);
BoundaryFill
(
x
,
y
+
1
,
FillColor
,
BoundaryColor
);
BoundaryFill
(
x
+
1
,
y
,
FillColor
,

BoundaryColor
);
BoundaryFill
(
x
,
y
-
1
,
FillColor
,
BoundaryColor
);
}
}

// Boundary Fill
Nhận xét
Thuật toán này có thể sẽ không hoạt động chính xác khi có một số điểm nằm
trong vùng tô có màu là màu cần tô của vùng (FillColor). Để khắc phục điều
này, trước khi tô màu cần phải đảm bảo rằng toàn bộ các điểm thuộc về vùng
tô có màu khác màu tô.
Nhận xét rằng trong cài đặt thuật toán ở trên, việc gọi thực hiện đệ quy thuật
toán cho bốn điểm lân cận của điểm hiện hành không quan tâm tới một trong
bốn điểm đó đã được xét ở bước trước hay chưa. Ví dụ khi ta xét bốn điểm
lân cận của điểm hiện hành (x,y), thì khi gọi thực hiện đệ quy với điểm hiện hành
là một trong bốn điểm lân cận trên, (x,y) vẫn được xem là điểm lân cận của
chúng và lại được gọi thực hiện lại. Ta sẽ đưa ra một cải tiến nhỏ để khắc phục
điểm này, bằng cách mỗi lần xét điểm hiện hành (x,y) ta sẽ gọi 4 thủ tục riêng

để tô các điểm lân cận và trong 4 thủ tục này ta sẽ tránh gọi lại việc xét điểm
(x,y).
void

BoundaryFillEnhanced(int
x
,

int
y
,

int
F_Color
,

int
B_Color
)
{
int
CurrentColor
;
CurrentColor
=
getpixel
(
x
,
y

);
if((
CurrentColor
!=
B_Color
)&&
CurrentColor
!=
F_Color
))
{
putpixel
(
x
,
y
,
F_Color
);
FillLeft
(
x
-
1
,
y
,
F_Color
,
B_Color

);
FillTop
(
x
,
y
+
1
,
F_Color
,
B_Color
);
FillRight
(
x
+
1
,
y
,
F_Color
,
B_Color
);
FillBottom
(
x
,
y

-
1
,
F_Color
,
B_Color
);
}

×