bài này được cài đặt trên BorlanC nhưng về thuật toán thì no change
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <graphics.h>
#include <dos.h>
#define MAXVERTEX 20
#define MAXEDGE 20
#define TRUE 1
#define FALSE 0
int x,y;
typedef struct {
int x;
int y;
}POINT;//Dia chi con tro co toa do(x,y)
typedef struct{
int NumVertex;
POINT aVertex[MAXVERTEX];
}POLYGON;
typedef struct {
int NumPt;
float xPt[MAXEDGE];
}XINTERSECT;
typedef struct
{
int yMin; // Gia tri y nho nhat cua 2 dinh
float xIntersect; // Hoanh do giao diem cua canh & dong quet
float dxPerScan; // Gia tri 1/m
int DeltaY;
}EDGE;
typedef struct
{
int NumEdge;
EDGE aEdge[MAXEDGE];
}EDGELIST;
POLYGON P; XINTERSECT a;EDGELIST EdgeList;
/*
Dat 1 canh vao danh sach canh.
Cac canh duoc sap theo thu tu giam dan cua yMin (yMin la gia tri y lon nhat cua 2 dinh 1 canh)
Xu li luon truong hop dong quet di ngang qua dinh ma tai do chi tinh 1 diem giao
*/
void PutEdgeInList(EDGELIST &EdgeList, POINT p1, POINT p2,int NextY)
{
EDGE EdgeTmp;
EdgeTmp.dxPerScan = float(p2.x-p1.x)/(p2.y-p1.y); // 1/m
if(p1.y < p2.y)
{
/*
Truong hop dong quet di ngang qua dinh la giao diem
cua 2 canh co huong y cung tang
*/
if(p2.y < NextY)
{
p2.y--;
p2.x -= EdgeTmp.dxPerScan;
}
EdgeTmp.yMin = p1.y;
EdgeTmp.xIntersect= p1.x;
EdgeTmp.DeltaY = abs(p2.y-p1.y)+1;
} // if
else
{/*Truong hop dong quet di ngang qua dinh la giao diem cua 2 canh co huong y cung giam*/
if(p2.y > NextY)
{
p2.y++;
p2.x+= EdgeTmp.dxPerScan;
}
EdgeTmp.yMin = p2.y;
EdgeTmp.xIntersect= p2.x;
EdgeTmp.DeltaY = abs(p2.y-p1.y)+1;
}//else
// xac dinh vi tri chen
int j = EdgeList.NumEdge;
while((j>0) && (EdgeList.aEdge[j-1].yMin>EdgeTmp.yMin))
{
EdgeList.aEdge[j] = EdgeList.aEdge[j-1];
j--;
}
// tien hanh chen dinh moi vao canh
EdgeList.NumEdge++;
EdgeList.aEdge[j] = EdgeTmp;
} // PutEdgeInList
/*
Tim dinh ke tiep sao cho khong nam tren cung duong thang voi dinh dang xet
*/
int FindNextY(POLYGON P, int id)
{
int j = (id+1)%P.NumVertex;
while((j<P.NumVertex)&&(P.aVertex[id].y == P.aVertex[j].y))
j++;
if(j<P.NumVertex)
return (P.aVertex[j].y);
return 0;
} // FindNextY
// Tao danh sach cac canh tu polygon da cho
void MakeSortedEdge(POLYGON P, EDGELIST &EdgeList,
int &TopScan, int &BottomScan)
{
TopScan = BottomScan = P.aVertex[0].y;
EdgeList.NumEdge = 0;
for(int i=0; i<P.NumVertex; i++)
{
// Truong hop canh khong phai la canh nam ngang if(P.aVertex[i].y != P.aVertex[i+1].y)
PutEdgeInList(EdgeList, P.aVertex[i], P.aVertex[i+1], FindNextY(P, i+1));
//else Xu li truong hop canh nam ngang
if(P.aVertex[i+1].y > TopScan)
TopScan = P.aVertex[i+1].y;
}
BottomScan = EdgeList.aEdge[0].yMin;
} //MakeSortedEdge
// Cap nhat lai hai con tro FirstId, LastId cho biet danhsach cac canh active
void UpdateActiveEdgeList(EDGELIST EdgeList, int yScan, int &FirstId, int &LastId)
{
while((FirstId<EdgeList.NumEdge-1) &&(EdgeList.aEdge[FirstId].DeltaY == 0))
FirstId++;
while((LastId<EdgeList.NumEdge-1) &&(EdgeList.aEdge[LastId+1].yMin<=yScan))
LastId++;
} // UpdateActiveEdgeList
void SortOnX(XINTERSECT & aIntersectPt)
{
for(int i=0; i<aIntersectPt.NumPt-1; i++)
{
int Min = i, t;
for(int j=i+1; j<aIntersectPt.NumPt; j++)
if( aIntersectPt.xPt[j] < aIntersectPt.xPt[Min])
Min = j;
t = aIntersectPt.xPt[Min];
aIntersectPt.xPt[Min] = aIntersectPt.xPt[i];
aIntersectPt.xPt[i] = t;
}
} // SortOnX
/*
Tim cac hoanh do giao diem cua cac canh cua da giac voi dong quet yScan. Sau khi tim cac hoanh do giao diem, ta sap xep lai theo chieu tang cua x
*/
void FindXIntersection(EDGELIST EdgeList, XINTERSECT &aIntersectPt, int FirstId, int LastId)
{
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
// To mau cac doan giao duoc tao boi tung cap hoanh do ke tiep nhau
#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;
}
}
} //UpdateEdgeList
void ScanLineFill(POLYGON P)
{
EDGELIST EdgeList;
XINTERSECT aIntersectPt;
int TopScan, BottomScan, FirstId, LastId;
//Tao danh sach tat ca cac canh ET
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);
//To mau cac doan duoc giao tao boi tung cap hoanh do ke tiep nhau
FillLine(aIntersectPt, i);
// Cap nhat lai thong tin cua cac canh de su dung cho dong quet ke tiep
UpdateEdgeList(EdgeList, FirstId, LastId);
}
delay(200);
}
void input()
{
int i;
printf("Nhap so canh cua da giac: "); scanf("%d",&P.NumVertex);
for(i=1;i<=P.NumVertex;i++)
{
printf("Nhap toa do dinh %d (x%d,y%d)=",i,i,i); scanf("%d%d",&P.aVertex[i].x,&P.aVertex[i].y);
}
}
void main()
{
int TopScan;
int BottomScan;
int n=DETECT,m;
initgraph(&n,&m,"");
input();
setcolor(GREEN);
MakeSortedEdge( P, EdgeList, TopScan, BottomScan);
x=getmaxx()/2,y=getmaxy()/2;
ScanLineFill(P);
getch();
closegraph;
}