📄 polygon.h
字号:
int i, MinIndexL, MaxIndex, MinIndexR, SkipFirst, Temp;
int MinPoint_Y, MaxPoint_Y, TopIsFlat, LeftEdgeDir;
int NextIndex, CurrentIndex, PreviousIndex;
int DeltaXN, DeltaYN, DeltaXP, DeltaYP;
struct HorLineList WorkingHLineList;
struct HorLine *EdgePointPtr;
POINT *VertexPtr;
/* Point to the vertex list */
VertexPtr = VertexList->PointPtr;
/* Scan the list to find the top and bottom of the polygon */
if (VertexList->Length == 0)
return(1); /* reject null polygons */
MaxPoint_Y = MinPoint_Y = VertexPtr[MinIndexL = MaxIndex = 0].y;
for (i = 1; i < VertexList->Length; i++) {
if (VertexPtr[i].y < MinPoint_Y)
MinPoint_Y = VertexPtr[MinIndexL = i].y; /* new top */
else if (VertexPtr[i].y > MaxPoint_Y)
MaxPoint_Y = VertexPtr[MaxIndex = i].y; /* new bottom */
}
if (MinPoint_Y == MaxPoint_Y)
return(1); /* polygon is 0-height; avoid infinite loop below */
/* Scan in ascending order to find the last top-edge point */
MinIndexR = MinIndexL;
while (VertexPtr[MinIndexR].y == MinPoint_Y)
INDEX_FORWARD(MinIndexR);
INDEX_BACKWARD(MinIndexR); /* back up to last top-edge point */
/* Now scan in descending order to find the first top-edge point */
while (VertexPtr[MinIndexL].y == MinPoint_Y)
INDEX_BACKWARD(MinIndexL);
INDEX_FORWARD(MinIndexL); /* back up to first top-edge point */
/* Figure out which direction through the vertex list from the top
vertex is the left edge and which is the right */
LeftEdgeDir = -1; /* assume left edge runs down thru vertex list */
if ((TopIsFlat = (VertexPtr[MinIndexL].x !=
VertexPtr[MinIndexR].x) ? 1 : 0) == 1) {
/* If the top is flat, just see which of the ends is leftmost */
if (VertexPtr[MinIndexL].x > VertexPtr[MinIndexR].x) {
LeftEdgeDir = 1; /* left edge runs up through vertex list */
Temp = MinIndexL; /* swap the indices so MinIndexL */
MinIndexL = MinIndexR; /* points to the start of the left */
MinIndexR = Temp; /* edge, similarly for MinIndexR */
}
} else {
/* Point to the downward end of the first line of each of the
two edges down from the top */
NextIndex = MinIndexR;
INDEX_FORWARD(NextIndex);
PreviousIndex = MinIndexL;
INDEX_BACKWARD(PreviousIndex);
/* Calculate X and Y lengths from the top vertex to the end of
the first line down each edge; use those to compare slopes
and see which line is leftmost */
DeltaXN = VertexPtr[NextIndex].x - VertexPtr[MinIndexL].x;
DeltaYN = VertexPtr[NextIndex].y - VertexPtr[MinIndexL].y;
DeltaXP = VertexPtr[PreviousIndex].x - VertexPtr[MinIndexL].x;
DeltaYP = VertexPtr[PreviousIndex].y - VertexPtr[MinIndexL].y;
if (((long)DeltaXN * DeltaYP - (long)DeltaYN * DeltaXP) < 0L) {
LeftEdgeDir = 1; /* left edge runs up through vertex list */
Temp = MinIndexL; /* swap the indices so MinIndexL */
MinIndexL = MinIndexR; /* points to the start of the left */
MinIndexR = Temp; /* edge, similarly for MinIndexR */
}
}
/* Set the # of scan lines in the polygon, skipping the bottom edge
and also skipping the top vertex if the top isn't flat because
in that case the top vertex has a right edge component, and set
the top scan line to draw, which is likewise the second line of
the polygon unless the top is flat */
if ((WorkingHLineList.Length =
MaxPoint_Y - MinPoint_Y - 1 + TopIsFlat) <= 0)
return(1); /* there's nothing to draw, so we're done */
WorkingHLineList.YStart = YOffset + MinPoint_Y + 1 - TopIsFlat;
/* Get memory in which to store the line list we generate */
if ((WorkingHLineList.HLinePtr =
(struct HorLine *) (malloc(sizeof(struct HorLine) *
WorkingHLineList.Length))) == NULL)
return(0); /* couldn't get memory for the line list */
/* Scan the left edge and store the boundary points in the list */
/* Initial pointer for storing scan converted left-edge coords */
EdgePointPtr = WorkingHLineList.HLinePtr;
/* Start from the top of the left edge */
PreviousIndex = CurrentIndex = MinIndexL;
/* Skip the first point of the first line unless the top is flat;
if the top isn't flat, the top vertex is exactly on a right
edge and isn't drawn */
SkipFirst = TopIsFlat ? 0 : 1;
/* Scan convert each line in the left edge from top to bottom */
do {
INDEX_MOVE(CurrentIndex,LeftEdgeDir);
ScanEdge(VertexPtr[PreviousIndex].x + XOffset,
VertexPtr[PreviousIndex].y,
VertexPtr[CurrentIndex].x + XOffset,
VertexPtr[CurrentIndex].y, 1, SkipFirst, &EdgePointPtr);
PreviousIndex = CurrentIndex;
SkipFirst = 0; /* scan convert the first point from now on */
} while (CurrentIndex != MaxIndex);
/* Scan the right edge and store the boundary points in the list */
EdgePointPtr = WorkingHLineList.HLinePtr;
PreviousIndex = CurrentIndex = MinIndexR;
SkipFirst = TopIsFlat ? 0 : 1;
/* Scan convert the right edge, top to bottom. X coordinates are
adjusted 1 to the left, effectively causing scan conversion of
the nearest points to the left of but not exactly on the edge */
do {
INDEX_MOVE(CurrentIndex,-LeftEdgeDir);
ScanEdge(VertexPtr[PreviousIndex].x + XOffset - 1,
VertexPtr[PreviousIndex].y,
VertexPtr[CurrentIndex].x + XOffset - 1,
VertexPtr[CurrentIndex].y, 0, SkipFirst, &EdgePointPtr);
PreviousIndex = CurrentIndex;
SkipFirst = 0; /* scan convert the first point from now on */
} while (CurrentIndex != MaxIndex);
/* Draw the line list representing the scan converted polygon */
DrawHorizontalLineList(&WorkingHLineList, pDraw);
/* Release the line list's memory and we're successfully done */
free(WorkingHLineList.HLinePtr);
return(1);
}
int FillConvexFloatPolygon(FloatPtListHeader * VertexList, int XOffset, int YOffset, CCEDraw* pDraw)
{
int i, MinIndexL, MaxIndex, MinIndexR, SkipFirst, Temp;
int MinPoint_Y, MaxPoint_Y, TopIsFlat, LeftEdgeDir;
int NextIndex, CurrentIndex, PreviousIndex;
int DeltaXN, DeltaYN, DeltaXP, DeltaYP;
struct HorLineList WorkingHLineList;
struct HorLine *EdgePointPtr;
FLOATPOINT *VertexPtr;
/* Point to the vertex list */
VertexPtr = VertexList->PointPtr;
/* Scan the list to find the top and bottom of the polygon */
if (VertexList->Length == 0)
return(1); /* reject null polygons */
MaxPoint_Y = MinPoint_Y = VertexPtr[MinIndexL = MaxIndex = 0].y;
for (i = 1; i < VertexList->Length; i++) {
if (VertexPtr[i].y < MinPoint_Y)
MinPoint_Y = VertexPtr[MinIndexL = i].y; /* new top */
else if (VertexPtr[i].y > MaxPoint_Y)
MaxPoint_Y = VertexPtr[MaxIndex = i].y; /* new bottom */
}
if (MinPoint_Y == MaxPoint_Y)
return(1); /* polygon is 0-height; avoid infinite loop below */
/* Scan in ascending order to find the last top-edge point */
MinIndexR = MinIndexL;
while (VertexPtr[MinIndexR].y == MinPoint_Y)
INDEX_FORWARD(MinIndexR);
INDEX_BACKWARD(MinIndexR); /* back up to last top-edge point */
/* Now scan in descending order to find the first top-edge point */
while (VertexPtr[MinIndexL].y == MinPoint_Y)
INDEX_BACKWARD(MinIndexL);
INDEX_FORWARD(MinIndexL); /* back up to first top-edge point */
/* Figure out which direction through the vertex list from the top
vertex is the left edge and which is the right */
LeftEdgeDir = -1; /* assume left edge runs down thru vertex list */
if ((TopIsFlat = (VertexPtr[MinIndexL].x !=
VertexPtr[MinIndexR].x) ? 1 : 0) == 1) {
/* If the top is flat, just see which of the ends is leftmost */
if (VertexPtr[MinIndexL].x > VertexPtr[MinIndexR].x) {
LeftEdgeDir = 1; /* left edge runs up through vertex list */
Temp = MinIndexL; /* swap the indices so MinIndexL */
MinIndexL = MinIndexR; /* points to the start of the left */
MinIndexR = Temp; /* edge, similarly for MinIndexR */
}
} else {
/* Point to the downward end of the first line of each of the
two edges down from the top */
NextIndex = MinIndexR;
INDEX_FORWARD(NextIndex);
PreviousIndex = MinIndexL;
INDEX_BACKWARD(PreviousIndex);
/* Calculate X and Y lengths from the top vertex to the end of
the first line down each edge; use those to compare slopes
and see which line is leftmost */
DeltaXN = VertexPtr[NextIndex].x - VertexPtr[MinIndexL].x;
DeltaYN = VertexPtr[NextIndex].y - VertexPtr[MinIndexL].y;
DeltaXP = VertexPtr[PreviousIndex].x - VertexPtr[MinIndexL].x;
DeltaYP = VertexPtr[PreviousIndex].y - VertexPtr[MinIndexL].y;
if (((long)DeltaXN * DeltaYP - (long)DeltaYN * DeltaXP) < 0L) {
LeftEdgeDir = 1; /* left edge runs up through vertex list */
Temp = MinIndexL; /* swap the indices so MinIndexL */
MinIndexL = MinIndexR; /* points to the start of the left */
MinIndexR = Temp; /* edge, similarly for MinIndexR */
}
}
/* Set the # of scan lines in the polygon, skipping the bottom edge
and also skipping the top vertex if the top isn't flat because
in that case the top vertex has a right edge component, and set
the top scan line to draw, which is likewise the second line of
the polygon unless the top is flat */
if ((WorkingHLineList.Length =
MaxPoint_Y - MinPoint_Y - 1 + TopIsFlat) <= 0)
return(1); /* there's nothing to draw, so we're done */
WorkingHLineList.YStart = YOffset + MinPoint_Y + 1 - TopIsFlat;
/* Get memory in which to store the line list we generate */
if ((WorkingHLineList.HLinePtr =
(struct HorLine *) (malloc(sizeof(struct HorLine) *
WorkingHLineList.Length))) == NULL)
return(0); /* couldn't get memory for the line list */
/* Scan the left edge and store the boundary points in the list */
/* Initial pointer for storing scan converted left-edge coords */
EdgePointPtr = WorkingHLineList.HLinePtr;
/* Start from the top of the left edge */
PreviousIndex = CurrentIndex = MinIndexL;
/* Skip the first point of the first line unless the top is flat;
if the top isn't flat, the top vertex is exactly on a right
edge and isn't drawn */
SkipFirst = TopIsFlat ? 0 : 1;
/* Scan convert each line in the left edge from top to bottom */
do {
INDEX_MOVE(CurrentIndex,LeftEdgeDir);
ScanEdge(VertexPtr[PreviousIndex].x + XOffset,
VertexPtr[PreviousIndex].y,
VertexPtr[CurrentIndex].x + XOffset,
VertexPtr[CurrentIndex].y, 1, SkipFirst, &EdgePointPtr);
PreviousIndex = CurrentIndex;
SkipFirst = 0; /* scan convert the first point from now on */
} while (CurrentIndex != MaxIndex);
/* Scan the right edge and store the boundary points in the list */
EdgePointPtr = WorkingHLineList.HLinePtr;
PreviousIndex = CurrentIndex = MinIndexR;
SkipFirst = TopIsFlat ? 0 : 1;
/* Scan convert the right edge, top to bottom. X coordinates are
adjusted 1 to the left, effectively causing scan conversion of
the nearest points to the left of but not exactly on the edge */
do {
INDEX_MOVE(CurrentIndex,-LeftEdgeDir);
ScanEdge(VertexPtr[PreviousIndex].x + XOffset - 1,
VertexPtr[PreviousIndex].y,
VertexPtr[CurrentIndex].x + XOffset - 1,
VertexPtr[CurrentIndex].y, 0, SkipFirst, &EdgePointPtr);
PreviousIndex = CurrentIndex;
SkipFirst = 0; /* scan convert the first point from now on */
} while (CurrentIndex != MaxIndex);
/* Draw the line list representing the scan converted polygon */
DrawHorizontalLineList(&WorkingHLineList, pDraw);
/* Release the line list's memory and we're successfully done */
free(WorkingHLineList.HLinePtr);
return(1);
}
void DrawHorizontalLineList(struct HorLineList * HLineListPtr, CCEDraw* pDraw)
{
struct HorLine *HLinePtr;
int Y, X;
/* Point to the XStart/XEnd descriptor for the first (top)
horizontal line */
HLinePtr = HLineListPtr->HLinePtr;
/* Draw each horizontal line in turn, starting with the top one and
advancing one line each time */
for (Y = HLineListPtr->YStart; Y < (HLineListPtr->YStart +
HLineListPtr->Length); Y++, HLinePtr++) {
/* Draw each pixel in the current horizontal line in turn,
starting with the leftmost one */
pDraw->DrawHLine( HLinePtr->XStart, Y, HLinePtr->XEnd, Y, pDraw->m_pBrush->m_Color );
//for (X = HLinePtr->XStart; X <= HLinePtr->XEnd; X++)
//pDraw->DrawPixel( X, Y, pDraw->m_pBrush->m_Color );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -