示例#1
0
void clip(double x0, double y0, double x1, double y1)
{
outcode outcode0, outcode1, outcodeOut;
int accept = FALSE, done = FALSE;
outcode0 = CompOutCode(x0, y0);
outcode1 = CompOutCode(x1, y1);
do
{
if (!(outcode0 | outcode1))
{
accept = TRUE;
done = TRUE;
}
else if (outcode0 & outcode1)
done = TRUE;
else
{
double x, y;
outcodeOut = outcode0 ? outcode0 : outcode1;
if (outcodeOut & TOP)
{
x = x0 + (x1 - x0) * (ymax - y0) / (y1 - y0);
y = ymax;
}
else if (outcodeOut & BOTTOM)
{
x = x0 + (x1 - x0) * (ymin - y0) / (y1 - y0);
y = ymin;
}
else if (outcodeOut & RIGHT)
{
y = y0 + (y1 - y0) * (xmax - x0) / (x1 - x0);
x = xmax;
}
else
{
y = y0 + (y1 - y0) * (xmin - x0) / (x1 - x0);
x = xmin;
}
if (outcodeOut == outcode0)
{
x0 = x;
y0 = y;
outcode0 = CompOutCode(x0, y0);
}
else
{
x1 = x;
y1 = y;
outcode1 = CompOutCode(x1, y1);
}
}
} while (done == FALSE);
if (accept)
line(x0, y0, x1, y1);
rectangle(xmin, ymin, xmax, ymax);
}
示例#2
0
文件: cutil.cpp 项目: AluOne/OpenCPN
ClipResult cohen_sutherland_line_clip_d (double *x0, double *y0, double *x1, double *y1,
                                         double xmin_, double xmax_, double ymin_, double ymax_)
{
      /* Cohen-Sutherland clipping algorithm for line P0=(x1,y0) to P1=(x1,y1)
    and clip rectangle with diagonal from (xmin,ymin) to (xmax,ymax).*/
    struct LOC_cohen_sutherland_line_clip V;
    int accept = CFALSE, done = CFALSE;
    ClipResult clip = Visible;
    outcode outcode0, outcode1, outcodeOut;
    /*Outcodes for P0,P1, and whichever point lies outside the clip rectangle*/
    double x=0., y=0.;

    V.xmin = xmin_;
    V.xmax = xmax_;
    V.ymin = ymin_;
    V.ymax = ymax_;
    CompOutCode(*x0, *y0, &outcode0, &V);
    CompOutCode(*x1, *y1, &outcode1, &V);
    do {
        if (outcode0 == 0 && outcode1 == 0) {   /*Trivial accept and exit*/
            accept = CTRUE;
            done = CTRUE;
        } else if ((outcode0 & outcode1) != 0) {
            clip = Invisible;
            done = CTRUE;
        }
        /*Logical intersection is true, so trivial reject and exit.*/
        else {
            clip = Visible;
                        /*Failed both tests, so calculate the line segment to clip;
            from an outside point to an intersection with clip edge.*/
            /*At least one endpoint is outside the clip rectangle; pick it.*/
            if (outcode0 != 0)
                outcodeOut = outcode0;
            else
                outcodeOut = outcode1;
                        /*Now find intersection point;
            use formulas y=y0+slope*(x-x0),x=x0+(1/slope)*(y-y0).*/

            if (((1L << ((long)TOP)) & outcodeOut) != 0) {
                /*Divide line at top of clip rectangle*/
                x = *x0 + (*x1 - *x0) * (V.ymax - *y0) / (*y1 - *y0);
                y = V.ymax;
            } else if (((1L << ((long)BOTTOM)) & outcodeOut) != 0) {
                /*Divide line at bottom of clip rectangle*/
                x = *x0 + (*x1 - *x0) * (V.ymin - *y0) / (*y1 - *y0);
                y = V.ymin;
            } else if (((1L << ((long)RIGHT)) & outcodeOut) != 0) {
                /*Divide line at right edge of clip rectangle*/
                y = *y0 + (*y1 - *y0) * (V.xmax - *x0) / (*x1 - *x0);
                x = V.xmax;
            } else if (((1L << ((long)LEFT)) & outcodeOut) != 0) {
                /*Divide line at left edge of clip rectangle*/
                y = *y0 + (*y1 - *y0) * (V.xmin - *x0) / (*x1 - *x0);
                x = V.xmin;
            }
                        /*Now we move outside point to intersection point to clip,
            and get ready for next pass.*/
            if (outcodeOut == outcode0) {
                *x0 = x;
                *y0 = y;
                CompOutCode(*x0, *y0, &outcode0, &V);
            } else {
                *x1 = x;
                *y1 = y;
                CompOutCode(*x1, *y1, &outcode1, &V);
            }
        }
    } while (!done);
    return clip;
}