📄 lineclip.c
字号:
-----
| |
-----
| |E */
int Clip57(void)
{
void ClipBottomOrRightTocYmaxOrcXmax(void);
int ClipTopOrLeftTocYminOrcXmin(void);
ClipBottomOrRightTocYmaxOrcXmax();
return(ClipTopOrLeftTocYminOrcXmin());
}
/* Function HandleFirstPointNull advances the line drawing parameters
1 point. Returns 1 if that was the only point, so the line is now
invisible, or 0 if there are still visible points. */
int HandleFirstPointNull(void)
{
switch (lineDir)
{
case 0: /* r->l, t->b Ymajor */
errTermL += errTermAdjUpL;
/* do we advance along the minor axis? */
if (errTermL >= 0)
{ /* yes */
dRect.Xmin--; /* advance along the X (minor) axis */
errTermL -= errTermAdjDownL; /* adjust the error term
back down */
}
/* also does case 1 */
case 1: /* vertical top->bottom */
dRect.Ymin++; /* advance to the second point along the Y
(major) axis */
majorAxisLengthM1--; /* count off the first point */
if (majorAxisLengthM1 < 0) return(1); /* done with line */
return(0);
case 2: /* l->r, t->b Ymajor */
dRect.Ymin++; /* advance to the second point along the Y
(major) axis */
errTermL += errTermAdjUpL;
/* do we advance along the minor axis? */
if (errTermL >= 0)
{ /* yes */
dRect.Xmin++; /* advance along the X (minor) axis */
errTermL -= errTermAdjDownL; /* adjust the error term
back down */
}
majorAxisLengthM1--; /* count off the first point */
if (majorAxisLengthM1 < 0) return(1); /* done with line */
return(0);
case 3: /* l->r, t->b diag */
dRect.Xmin++; /* advance to the second point */
dRect.Ymin++;
majorAxisLengthM1--; /* count off the first point */
if (majorAxisLengthM1 < 0) return(1); /* done with line */
return(0);
case 4: /* l->r, t->b Xmajor */
errTermL += errTermAdjUpL;
/* do we advance along the minor axis? */
if (errTermL >= 0)
{ /* yes */
dRect.Ymin++; /* advance along the Y (minor) axis */
errTermL -= errTermAdjDownL; /* adjust the error term
back down */
}
/* also does case 1 */
case 5: /* vertical top->bottom */
dRect.Xmin++; /* advance to the second point along the X
(major) axis */
majorAxisLengthM1--; /* count off the first point */
if (majorAxisLengthM1 < 0) return(1); /* done with line */
return(0);
case 6: /* r->l, t->b diag */
dRect.Xmin--; /* advance to the second point */
dRect.Ymin++;
majorAxisLengthM1--; /* count off the first point */
if (majorAxisLengthM1 < 0) return(1); /* done with line */
return(0);
case 7: /* r->l, t->b Xmajor */
errTermL += errTermAdjUpL;
/* do we advance along the minor axis? */
if (errTermL >= 0)
{ /* yes */
dRect.Ymin++; /* advance along the Y (minor) axis */
errTermL -= errTermAdjDownL; /* adjust the error term
back down */
}
dRect.Xmin--; /* advance to the second point along the X
(major) axis */
majorAxisLengthM1--; /* count off the first point */
if (majorAxisLengthM1 < 0) return(1); /* done with line */
return(0);
}
return(0);
}
/* Function ClipRightTocXmax clips the end of a left->right line to
match cXmax.
Note that end clipping should be performed before start clipping to
avoid possible complications with fractional start coordinates.
Sets new line length-1 in majorAxisLengthM1. */
void ClipRightTocXmax(void)
{
if (lineDir >= 3)
{ /* Xmajor, which is easy--just chop off the end */
majorAxisLengthM1 = cRect.Xmax - dRect.Xmin; /* # of points
yet to draw */
return;
}
/* we'll have to figure out the intercept */
/* calculate new length - 1 */
majorAxisLengthM1 = (errTermAdjDownL * (cRect.Xmax - dRect.Xmin)
- errTermL - 1) / errTermAdjUpL;
return;
}
/* Function ClipLeftTocXmin clips the end of a right->left line to
match cXmin. */
void ClipLeftTocXmin(void)
{
if (lineDir >= 3)
{ /* Xmajor, which is easy--just chop off the end */
majorAxisLengthM1 = dRect.Xmin - cRect.Xmin; /* # of points
yet to draw */
return;
}
/* we'll have to figure out the intercept */
/* calculate new length - 1 */
majorAxisLengthM1 = (errTermAdjDownL * (dRect.Xmin - cRect.Xmin)
- errTermL - 1) / errTermAdjUpL;
return;
}
/* Function ClipBottomTocYmax clips the end of a top->bottom line to
match cYmax. */
void ClipBottomTocYmax(void)
{
if (lineDir < 3)
{ /* Ymajor, which is easy--just chop off the end */
majorAxisLengthM1 = cRect.Ymax - dRect.Ymin; /* # of points
yet to draw */
return;
}
/* we'll have to figure out the intercept */
/* calculate new length - 1 */
majorAxisLengthM1 = (errTermAdjDownL * (cRect.Ymax - dRect.Ymin)
- errTermL - 1) / errTermAdjUpL;
return;
}
/* Function ClipBottomOrRightTocYmaxOrcXmax clips the end of a top->bottom,
left->right line to match cYmax or cXmax, whichever it crosses first. */
void ClipBottomOrRightTocYmaxOrcXmax(void)
{
void ClipBottomTocYmax(void);
void ClipRightTocXmax(void);
int temMajorAxisLength;
ClipBottomTocYmax(); /* get count until cYmax crossed */
temMajorAxisLength = majorAxisLengthM1;
/* BobB 5/8/98 - corrected the following line
ClipRightTocXmax;*/ /* get count until cXmax crossed */
ClipRightTocXmax(); /* get count until cXmax crossed */
/* use the smaller of the two */
if (majorAxisLengthM1 > temMajorAxisLength)
majorAxisLengthM1 = temMajorAxisLength;
return;
}
/* Function ClipBottomOrLeftTocYmaxOrcXmin clips the end of a top->bottom,
right->lef line to match cYmax or cXmin, whichever it crosses first. */
void ClipBottomOrLeftTocYmaxOrcXmin(void)
{
void ClipBottomTocYmax(void);
void ClipLeftTocXmin(void);
int temMajorAxisLength;
ClipBottomTocYmax(); /* get count until cYmax crossed */
temMajorAxisLength = majorAxisLengthM1;
/* BobB 5/8/98 - corrected the following line
ClipLeftTocXmin;*/ /* get count until cXmax crossed */
ClipLeftTocXmin(); /* get count until cXmax crossed */
/* use the smaller of the two */
if (majorAxisLengthM1 > temMajorAxisLength)
majorAxisLengthM1 = temMajorAxisLength;
return;
}
/* Function ClipTopTocYmin clips the start of a top->bottom line to
match cYmin. */
void ClipTopTocYmin(void)
{
int clipPoints, errPoints;
clipPoints = cRect.Ymin - dRect.Ymin; /* # of points to clip
edge along perpendicular axis */
dRect.Ymin = cRect.Ymin; /* new start Y coordinate */
if (lineDir < 3)
{ /* Ymajor, which is easier--calculate the distance to the
intercept and advance errTermL, dXmin, and dYmin accordingly,
and remove the clipped points from minorAxisLengthM1 */
majorAxisLengthM1 -= clipPoints;
errTermL += (clipPoints * errTermAdjUpL) + errTermL;
if (errTermL < 0) return; /* the error term didn't turn over
even once, so the minor axis doesn't advance at all */
errPoints = (errTermL % errTermAdjDownL);
clipPoints = (errTermL / errTermAdjDownL) + 1;
if (lineDir == 0)
{
dRect.Xmin -= clipPoints;
}
else
{
dRect.Xmin += clipPoints;
}
errTermL = errPoints - errTermAdjDownL;
return;
}
/* we'll have to figure out the intercept */
/* calculate calculate # points to skip */
errPoints = errTermAdjDownL * (clipPoints - 1);
clipPoints = ((errPoints - errTermL - 1) / errTermAdjUpL) + 1;
majorAxisLengthM1 -= clipPoints;
if (lineDir >= 6)
{
dRect.Xmin -= clipPoints;
}
else
{
dRect.Xmin += clipPoints;
}
errTermL += ((clipPoints * errTermAdjUpL) - errPoints -
errTermAdjDownL);
return;
}
/* Function ClipLeftTocXminS clips the start of a left->right line to
match cXmin. */
void ClipLeftTocXminS(void)
{
int clipPoints, errPoints;
clipPoints = cRect.Xmin - dRect.Xmin; /* # of points to clip
edge along horizontal axis */
dRect.Xmin = cRect.Xmin; /* new start X coordinate */
if (lineDir >= 3)
{ /* Xmajor, which is easier--calculate the distance to the
intercept and advance errTermL, dXmin, and dYmin accordingly,
and remove the clipped points from minorAxisLengthM1 */
majorAxisLengthM1 -= clipPoints;
errTermL += (clipPoints * errTermAdjUpL) + errTermL;
if (errTermL < 0) return; /* the error term didn't turn over
even once, so the minor axis doesn't advance at all */
errPoints = (errTermL % errTermAdjDownL);
clipPoints = (errTermL / errTermAdjDownL) + 1;
dRect.Ymin += clipPoints;
errTermL = errPoints - errTermAdjDownL;
return;
}
/* we'll have to figure out the intercept */
/* calculate calculate # points to skip */
errPoints = errTermAdjDownL * (clipPoints - 1);
clipPoints = ((errPoints - errTermL - 1) / errTermAdjUpL) + 1;
majorAxisLengthM1 -= clipPoints;
dRect.Ymin += clipPoints;
errTermL += ((clipPoints * errTermAdjUpL) - errPoints -
errTermAdjDownL);
return;
}
/* Function ClipRightTocXmaxS clips the start of a right->left line to
match cXmax. */
void ClipRightTocXmaxS(void)
{
int clipPoints, errPoints;
clipPoints = dRect.Xmin - cRect.Xmax; /* # of points to clip
edge along horizontal axis */
dRect.Xmin = cRect.Xmax; /* new start X coordinate */
if (lineDir >= 3)
{ /* Xmajor, which is easier--calculate the distance to the
intercept and advance errTermL, dXmin, and dYmin accordingly,
and remove the clipped points from minorAxisLengthM1 */
majorAxisLengthM1 -= clipPoints;
errTermL += (clipPoints * errTermAdjUpL) + errTermL;
if (errTermL < 0) return; /* the error term didn't turn over
even once, so the minor axis doesn't advance at all */
errPoints = (errTermL % errTermAdjDownL);
clipPoints = (errTermL / errTermAdjDownL) + 1;
dRect.Ymin += clipPoints;
errTermL = errPoints - errTermAdjDownL;
return;
}
/* we'll have to figure out the intercept */
/* calculate calculate # points to skip */
errPoints = errTermAdjDownL * (clipPoints - 1);
clipPoints = ((errPoints - errTermL - 1) / errTermAdjUpL) + 1;
majorAxisLengthM1 -= clipPoints;
dRect.Ymin += clipPoints;
errTermL += ((clipPoints * errTermAdjUpL) - errPoints -
errTermAdjDownL);
return;
}
/* Function ClipTopOrLeftTocYminOrcXmin clips the start of a
top->bottom, left->right line to match cYmin or cXmin, whichever
it crosses first. Returns 1 if the line isn't visible at all. */
int ClipTopOrLeftTocYminOrcXmin(void)
{
void ClipLeftTocXminS(void);
void ClipTopTocYmin(void);
int dXmin, dYmin, saveMajorAxis, saveErrTerm;
if (lineDir >= 3)
{ /* X major; try the cXmin intercept first and see if
it's the one we want */
dYmin = dRect.Ymin; /* preserve variables that will be altered */
dXmin = dRect.Xmin;
saveMajorAxis = majorAxisLengthM1;
saveErrTerm = errTermL;
ClipLeftTocXminS(); /* clip left */
/* is the new dYmin in the clip rect? */
if (dRect.Ymin > cRect.Ymin) return(1); /* no, it's above,
the line isn't visible */
if (dRect.Ymin < cRect.Ymin)
{ /* no, try cYmin clip */
errTermL = saveErrTerm; /* restore the variables to their
original state */
majorAxisLengthM1 = saveMajorAxis;
dRect.Xmin = dXmin;
dRect.Ymin = dYmin;
ClipTopTocYmin(); /* calculate cYmin clipping */
/* is the new dYmin in the clip rect? */
if (dRect.Xmin > cRect.Xmax) return(1); /* no */
}
return(0); /* yes, we have a usable intercept */
}
/* Y major line; try the cYmin intercept first and see if it's
the one we want */
dYmin = dRect.Ymin; /* preserve variables that will be altered */
dXmin = dRect.Xmin;
saveMajorAxis = majorAxisLengthM1;
saveErrTerm = errTermL;
ClipTopTocYmin(); /* clip top */
/* is the new dYmin in the clip rect? */
if (dRect.Xmin > cRect.Xmin) return(1); /* no, it's outside,
the line isn't visible */
if (dRect.Xmin < cRect.Xmin)
{ /* no, try cXmin clip */
errTermL = saveErrTerm; /* restore the variables to their
original state */
majorAxisLengthM1 = saveMajorAxis;
dRect.Xmin = dXmin;
dRect.Ymin = dYmin;
ClipLeftTocXminS(); /* calculate cXmin clipping */
/* is the new dYmin in the clip rect? */
if (dRect.Ymin > cRect.Ymax) return(1); /* no */
}
return(0); /* yes, we have a usable intercept */
}
/* Function ClipTopOrRightTocYminOrcXmax clips the start of a
top->bottom, right->left line to match cYmin or cXmax, whichever
it crosses first. Returns 1 if the line isn't visible at all. */
int ClipTopOrRightTocYminOrcXmax(void)
{
void ClipRightTocXmaxS(void);
void ClipTopTocYmin(void);
int dXmin, dYmin, saveMajorAxis, saveErrTerm;
if (lineDir >= 3)
{ /* X major; try the cXmin intercept first and see if
it's the one we want */
dYmin = dRect.Ymin; /* preserve variables that will be altered */
dXmin = dRect.Xmin;
saveMajorAxis = majorAxisLengthM1;
saveErrTerm = errTermL;
ClipRightTocXmaxS(); /* clip right */
/* is the new dYmin in the clip rect? */
if (dRect.Ymin > cRect.Ymin) return(1); /* no, it's above,
the line isn't visible */
if (dRect.Ymin < cRect.Ymin)
{ /* no, try cYmin clip */
errTermL = saveErrTerm; /* restore the variables to their
original state */
majorAxisLengthM1 = saveMajorAxis;
dRect.Xmin = dXmin;
dRect.Ymin = dYmin;
ClipTopTocYmin(); /* calculate cYmin clipping */
/* is the new dYmin in the clip rect? */
if (dRect.Xmin < cRect.Xmin) return(1); /* no */
}
return(0); /* yes, we have a usable intercept */
}
/* Y major line; try the cYmin intercept first and see if it's
the one we want */
dYmin = dRect.Ymin; /* preserve variables that will be altered */
dXmin = dRect.Xmin;
saveMajorAxis = majorAxisLengthM1;
saveErrTerm = errTermL;
ClipTopTocYmin(); /* clip top */
/* is the new dYmin in the clip rect? */
if (dRect.Xmin > cRect.Xmin) return(1); /* no, it's outside,
the line isn't visible */
if (dRect.Xmin < cRect.Xmin)
{ /* no, try cXmin clip */
errTermL = saveErrTerm; /* restore the variables to their
original state */
majorAxisLengthM1 = saveMajorAxis;
dRect.Xmin = dXmin;
dRect.Ymin = dYmin;
ClipRightTocXmaxS(); /* calculate cXmin clipping */
/* is the new dYmin in the clip rect? */
if (dRect.Ymin > cRect.Ymax) return(1); /* no */
}
return(0); /* yes, we have a usable intercept */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -