📄 xpol5.c
字号:
QArcEdge->StartY = QArcCenterY - QArcB; /* start Y = center Y - Y radius */
QArcEdge->Count = QArcB + 1; /* # of scan lines intersected by arc */
QArcEdge->TopToBottom = QArcTToB;
QArcEdge->XDirection = QArcDirection;
QArcEdge->CurrentX = QArcCenterX; /* X value when Y = 0 */
if (QArcDirection < 0 ) /* rightward arc? */
{ /* no, final X is X radius distance to left of center */
QArcEdge->qaFinalX = QArcCenterX - QArcA;
}
else
{ /* yes, final X is X radius distance to right of center */
QArcEdge->qaFinalX = QArcCenterX + QArcA;
}
if (QArcB == 0) /* zero height? */
{ /* yes, flat line, so go right to the end */
QArcEdge->CurrentX =(short) QArcEdge->qaFinalX;
return;
}
if (QArcA == 0) /* is this a vertical line? */
{
QArcEdge->StepVector = &StepVertical; /* stepping routine */
return;
}
QArcEdge->qaASq = QArcA * QArcA; /* X radius squared */
QArcEdge->qaASqX2 = QArcEdge->qaASq + QArcEdge->qaASq; /* X radius ** 2 * 2 */
QArcEdge->qaBSq = QArcB * QArcB; /* Y radius squared */
QArcEdge->qaBSqX2 = QArcEdge->qaBSq + QArcEdge->qaBSq; /* Y radius ** 2 * 2 */
QArcEdge->StepVector = &StepQATopNativeSize; /* set up scanning vector */
QArcEdge->qaXAdjust.fUpper = 0; /* initial xadjust = 0 */
QArcEdge->qaXAdjust.fLower = 0;
/* Y adjust = 2*(XRadius**2)*YRadius */
dblTmp.fUpper = (QArcB >> 16);
dblTmp.fLower = (QArcB << 16);
dblTmp2.fUpper = (QArcEdge->qaASqX2 >> 16);
dblTmp2.fLower = (QArcEdge->qaASqX2 << 16);
dFix_mul(&dblTmp2, &dblTmp, &QArcEdge->qaYAdjust);
/* initial qaErrTerm = ((Xradius**2 + Yradius**2) / 4) - XRadius**2*YRadius */
dblTmp.fUpper = (QArcEdge->qaASq + QArcEdge->qaBSq);
dblTmp.fLower = (dblTmp.fUpper << 15);
dblTmp.fUpper = (dblTmp.fUpper >> 17);
dFix_sub(&dblTmp, &QArcEdge->qaYAdjust, &QArcEdge->qaErrTerm);
QArcEdge->qaErrTerm.fLower = (((unsigned long)QArcEdge->qaErrTerm.fUpper) << 31) |
(QArcEdge->qaErrTerm.fLower >> 1);
QArcEdge->qaErrTerm.fUpper = (QArcEdge->qaErrTerm.fUpper >> 1);
/* precompensate for adjustments StepQATopNativeSize will do on the initial
scanning call */
dFix_add(&QArcEdge->qaErrTerm, &QArcEdge->qaYAdjust, &QArcEdge->qaErrTerm);
dFix_add(&QArcEdge->qaYAdjust, &dblTmp2, &QArcEdge->qaYAdjust);
/* scan to the maximum extent on the first scan line of the arc */
StepQATopNativeSize(QArcEdge);
return;
}
#else
void mwSTQA(qarcState *QArcEdge, int QArcA, int QArcB, int QArcCenterX,
int QArcCenterY, int QArcDirection, int QArcTToB)
{
QArcEdge->StartY = QArcCenterY - QArcB; /* start Y = center Y - Y radius */
QArcEdge->Count = QArcB + 1; /* # of scan lines intersected by arc */
QArcEdge->TopToBottom = QArcTToB;
QArcEdge->XDirection = QArcDirection;
QArcEdge->CurrentX = QArcCenterX; /* X value when Y = 0 */
if (QArcDirection < 0 ) /* rightward arc? */
{ /* no, final X is X radius distance to left of center */
QArcEdge->qaFinalX = QArcCenterX - QArcA;
}
else
{ /* yes, final X is X radius distance to right of center */
QArcEdge->qaFinalX = QArcCenterX + QArcA;
}
if (QArcB == 0) /* zero height? */
{ /* yes, flat line, so go right to the end */
QArcEdge->CurrentX =(short) QArcEdge->qaFinalX;
return;
}
if (QArcA == 0) /* is this a vertical line? */
{
QArcEdge->StepVector = &StepVertical; /* stepping routine */
return;
}
QArcEdge->qaASq = QArcA * QArcA; /* X radius squared */
QArcEdge->qaASqX2 = QArcEdge->qaASq + QArcEdge->qaASq; /* X radius ** 2 * 2 */
QArcEdge->qaBSq = QArcB * QArcB; /* Y radius squared */
QArcEdge->qaBSqX2 = QArcEdge->qaBSq + QArcEdge->qaBSq; /* Y radius ** 2 * 2 */
QArcEdge->StepVector = &StepQATopNativeSize; /* set up scanning vector */
QArcEdge->qaXAdjust = 0; /* initial xadjust = 0 */
/* Y adjust = 2*(XRadius**2)*YRadius */
QArcEdge->qaYAdjust = QArcEdge->qaASqX2 * QArcB;
/* initial qaErrTerm = ((Xradius**2 + Yradius**2) / 4) - XRadius**2*YRadius */
/* BobB 2/2/99 - corrected the following line for floating point 2.0
QArcEdge->qaErrTerm = ((((QArcEdge->qaASq + QArcEdge->qaBSq) / 2) -
QArcEdge->qaYAdjust) / 2); */
QArcEdge->qaErrTerm = ((((QArcEdge->qaASq + QArcEdge->qaBSq) / 2.0) -
QArcEdge->qaYAdjust) / 2.0);
/* precompensate for adjustments StepQATopNativeSize will do on the initial
scanning call */
QArcEdge->qaErrTerm += QArcEdge->qaYAdjust;
QArcEdge->qaYAdjust += QArcEdge->qaASqX2;
/* scan to the maximum extent on the first scan line of the arc */
StepQATopNativeSize(QArcEdge);
return;
}
#endif
/* Function mwSBQA sets up a bottom quadrant arc edge (a 90-degree arc edge
entity, either from 270 to 180 or from 270 to 360).
QArcEdge = pointer to qarcState to set up
QArcA = X radius of arc (>=0)
QArcB = Y radius of arc (>=0)
QArcCenterX = X center point of arc
QArcCenterY = Y center point of arc
QArcDirection = 1 if arc goes from 270 to 180, -1 if arc goes from 270 to 360
***no other values are acceptable for QArcDirection***
QArcTToB = 1 if arc is interpreted as top to bottom, -1 if bottom to top
***no other values are acceptable for QArcTToB*** */
#ifdef FIXPOINT
void mwSBQA(qarcState *QArcEdge, int QArcA, int QArcB, int QArcCenterX,
int QArcCenterY, int QArcDirection, int QArcTToB)
{
int dFix_sub(dblFix *first, dblFix *second, dblFix *result);
int dFix_mul(dblFix *first, dblFix *second, dblFix *result);
byte StepVertical(qarcState *CurrentEdge);
dblFix dblTmp, dblTmp2;
QArcEdge->StartY = QArcCenterY; /* start Y = center Y */
QArcEdge->Count = QArcB + 1; /* # of scan lines intersected by arc */
QArcEdge->TopToBottom = QArcTToB;
QArcEdge->XDirection = QArcDirection;
if (QArcDirection < 0 ) /* rightward arc? */
{ /* no, current X is X radius distance to right of center */
QArcEdge->CurrentX = QArcCenterX + QArcA;
}
else
{ /* yes, current X is X radius distance to left of center */
QArcEdge->CurrentX = QArcCenterX - QArcA;
}
if (QArcA == 0) /* is this a vertical line? */
{
QArcEdge->StepVector = &StepVertical; /* stepping routine */
return;
}
QArcEdge->qaASq = QArcA * QArcA; /* X radius squared */
QArcEdge->qaASqX2 = QArcEdge->qaASq + QArcEdge->qaASq; /* X radius ** 2 * 2 */
QArcEdge->qaBSq = QArcB * QArcB; /* Y radius squared */
QArcEdge->qaBSqX2 = QArcEdge->qaBSq + QArcEdge->qaBSq; /* Y radius ** 2 * 2 */
QArcEdge->StepVector = &StepQABottomNativeSize; /* set up scanning vector */
QArcEdge->qaYAdjust.fUpper = 0; /* initial yadjust = 0 */
QArcEdge->qaYAdjust.fLower = 0;
/* X adjust = 2*(YRadius**2)*XRadius */
dblTmp.fUpper = (QArcA >> 16);
dblTmp.fLower = (QArcA << 16);
dblTmp2.fUpper = (QArcEdge->qaBSqX2 >> 16);
dblTmp2.fLower = (QArcEdge->qaBSqX2 << 16);
dFix_mul(&dblTmp2, &dblTmp, &QArcEdge->qaXAdjust);
/* initial qaErrTerm = ((Xradius**2 + Yradius**2) / 4) - YRadius**2*XRadius */
dblTmp.fUpper = (QArcEdge->qaASq + QArcEdge->qaBSq);
dblTmp.fLower = (dblTmp.fUpper << 15);
dblTmp.fUpper = (dblTmp.fUpper >> 17);
dFix_sub(&dblTmp, &QArcEdge->qaXAdjust, &QArcEdge->qaErrTerm);
QArcEdge->qaErrTerm.fLower = (((unsigned long)QArcEdge->qaErrTerm.fUpper) << 31) |
(QArcEdge->qaErrTerm.fLower >> 1);
QArcEdge->qaErrTerm.fUpper = (QArcEdge->qaErrTerm.fUpper >> 1);
return;
}
#else
void mwSBQA(qarcState *QArcEdge, int QArcA, int QArcB, int QArcCenterX,
int QArcCenterY, int QArcDirection, int QArcTToB)
{
QArcEdge->StartY = QArcCenterY; /* start Y = center Y */
QArcEdge->Count = QArcB + 1; /* # of scan lines intersected by arc */
QArcEdge->TopToBottom = QArcTToB;
QArcEdge->XDirection = QArcDirection;
if (QArcDirection < 0 ) /* rightward arc? */
{ /* no, current X is X radius distance to right of center */
QArcEdge->CurrentX = QArcCenterX + QArcA;
}
else
{ /* yes, current X is X radius distance to left of center */
QArcEdge->CurrentX = QArcCenterX - QArcA;
}
if (QArcA == 0) /* is this a vertical line? */
{
QArcEdge->StepVector = &StepVertical; /* stepping routine */
return;
}
QArcEdge->qaASq = QArcA * QArcA; /* X radius squared */
QArcEdge->qaASqX2 = QArcEdge->qaASq + QArcEdge->qaASq; /* X radius ** 2 * 2 */
QArcEdge->qaBSq = QArcB * QArcB; /* Y radius squared */
QArcEdge->qaBSqX2 = QArcEdge->qaBSq + QArcEdge->qaBSq; /* Y radius ** 2 * 2 */
QArcEdge->StepVector = &StepQABottomNativeSize; /* set up scanning vector */
QArcEdge->qaYAdjust = 0; /* initial yadjust = 0 */
/* X adjust = 2*(YRadius**2)*XRadius */
QArcEdge->qaXAdjust = QArcEdge->qaBSqX2 * QArcA;
/* initial qaErrTerm = ((Xradius**2 + Yradius**2) / 4) - YRadius**2*XRadius */
/* BobB 2/2/99 - corrected the following line for floating point 2.0
QArcEdge->qaErrTerm = ((((QArcEdge->qaASq + QArcEdge->qaBSq) / 2) -
QArcEdge->qaXAdjust) / 2); */
QArcEdge->qaErrTerm = ((((QArcEdge->qaASq + QArcEdge->qaBSq) / 2.0) -
QArcEdge->qaXAdjust) / 2.0);
return;
}
#endif
/* Function mwSV sets up a vertical line edge.
VLEdge = pointer to Vedge-compatible edge
VLX = constant X, in global coords
VLY = initial Y, in global coords
VLHeight = # of pixels to draw
VLDir = -1 if left edge, 1 if right edge */
void mwSV(Vedge *VLEdge, int VLX, int VLY, int VLHeight, int VLDir)
{
VLEdge->StepVector = &StepVertical; /* stepping routine */
VLEdge->CurrentX = VLX; /* constant X value */
VLEdge->StartY = VLY; /* initial Y */
VLEdge->Count = VLHeight;
VLEdge->TopToBottom = VLDir;
return;
}
/* Function mwSLE sets up a straight line edge.
LineEdge = pointer to lineEdgeV to set up
XStart = X start coordinate of line
YStart = Y start coordinate of line
XEnd = X end coordinate of line
YEnd = Y end coordinate of line
LineEdgeTToB = 1 if line is interpreted as top to bottom,
-1 if bottom to top
***no other values are acceptable for LineEdgeTToB***
Assumes a valid line, of > 0 length, is passed in */
void mwSLE(lineEdgeV *LineEdge, int XStart, int YStart, int XEnd, int YEnd,
int LineEdgeTToB)
{
short startX;
short startY;
short endX;
short endY;
short deltaX;
short deltaY;
LineEdge->StepVector = &StepStraightEdge; /* stepping routine */
LineEdge->TopToBottom = LineEdgeTToB;
/* make sure the edge runs top->bottom */
if (YStart < YEnd)
{
startX = XStart;
startY = YStart;
endX = XEnd;
endY = YEnd;
}
else
{
startX = XEnd;
startY = YEnd;
endX = XStart;
endY = YStart;
}
LineEdge->CurrentX = startX;
LineEdge->StartY = startY;
deltaY = endY - startY; /* Count & ErrorTermAdjDown = DeltaY */
LineEdge->Count = deltaY;
LineEdge->ErrorTermAdjDownV = deltaY;
deltaX = endX - startX;
if (deltaX < 0)
{
LineEdge->XDirection = -1;
LineEdge->ErrorTermV = -deltaY;
deltaX = -deltaX;
}
else
{
LineEdge->XDirection = 1;
LineEdge->ErrorTermV = -1;
}
if (deltaY > deltaX) /* X major or Y major? */
{ /* Y major */
LineEdge->WholePixelXMoveV = 0;
LineEdge->ErrorTermAdjUpV = deltaX; /* ErrorTermAdjUp = Width */
return;
}
/* X major */
LineEdge->ErrorTermAdjUpV = deltaX % deltaY;
if (LineEdge->XDirection == 1)
{
LineEdge->WholePixelXMoveV = deltaX / deltaY;
return;
}
LineEdge->WholePixelXMoveV = - deltaX / deltaY;
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -