多边形裁剪错误?

时间:2018-03-11 19:29:39

标签: c++ graphics clipping

我一直试图用我的Sutherland-Hodgman Polygon Clipper算法来解决这个问题。填写多边形时,我会得到以下结果:enter image description here

我似乎无法弄清楚导致错误的原因,这是我的代码:

// @param in    the number of vertices in the polygon to be clipped
// @param inV   the incoming vertex list
// @param outV  the outgoing vertex list
// @param ll    the lower-left corner of the clipping rectangle
// @param ur    the upper-right corner of the clipping rectangle
//
// @return number of vertices in the polygon resulting after clipping

int Clipper::clipPolygon( int in, const Vertex inV[], Vertex outV[],
                          Vertex ll, Vertex ur )
{

    int out = 0, out2 = 0, out3 = 0, out4 = 0;

    Vertex  *outV2,  *outV3, *outV4; 

    // We clip entire figure by clipping on the 4 edges of the clipping window
    // each step will be stored, in *out pointers.

    SHPC(inV, outV, in, out, ll.x, ur.y, ll.x, ll.y); // left

    outV2 = new Vertex[out]; 

    SHPC(outV, outV2, out, out2, ll.x, ll.y, ur.x, ll.y); // bottom

    outV3 = new Vertex[out2]; 
    SHPC(outV2, outV3, out2, out3, ur.x, ll.y, ur.x, ur.y); // right

    outV4 = new Vertex[out3]; 
    SHPC(outV3, outV4, out3, out4, ur.x, ur.y, ll.x, ur.y); // top

    // we want outx and outy to store the final clipped polygons, which
    // means we need to get content of outx4 and outy4
    for (int i = 0; i < out; i++) { outV[i].x = outV4[i].x; outV[i].y = outV4[i].y; }
    // same principle for out value
    out = out4;

    delete[] outV2; 
    delete[] outV3;
    delete[] outV4;
    return out;
} 

void Clipper::SHPC(const Vertex inV[],
    Vertex outV[], int in, int &out,
    float x0, float y0, float x1, float y1) {

    float px = inV[in - 1].x, py = inV[in - 1].y; // last vertex is the initial “predecessor”

    float _x = px, _y = py;

    for (int j = 0; j < in; j++) {
        if (inside(inV[j].x, inV[j].y, x0, y0, x1, y1)) { // Cases 1 & 4
            if (inside(px, py, x0, y0, x1, y1)) { // Case 1
                output(inV[j].x, inV[j].y, out, outV);
            }
            else { // Case 4
                intersect(px, py, inV[j].x, inV[j].y, x0, y0, x1, y1, _x, _y);
                output(_x, _y, out, outV);
                output(inV[j].x, inV[j].y, out, outV);
            }
        }
        else { // Cases 2 & 3
            if (inside(px, py, x0, y0, x1, y1)) { // Case 2
                intersect(px, py, inV[j].x, inV[j].y, x0, y0, x1, y1, _x, _y);
                output(_x, _y, out, outV);
            } // Case 3 has no output 
        }

        px = inV[j].x;
        py = inV[j].y;

    } // for
}


// is point inside boundary?
bool Clipper::inside(float _x, float _y, float x0, float y0, float x1, float y1) {
    if (y0 == y1) { // horizontal edge
        if (x0 < x1) return _y >= y0;
        if (x0 > x1) return _y <= y0;
    } else { // vertical edge
        if (y1 > y0) return _x <= x0;
        if (y0 > y1) return _x >= x0;
    }
    return false;
}


// put point into vector, update length
void Clipper::output(float _x, float _y, int &out, Vertex outV[]) {
    outV[out].x = _x;
    outV[out++].y = _y;
}


// compute intersection point, put point into newpoint parameter
void Clipper::intersect(float sx, float sy, float ex, float ey, float x0, float y0, float x1, float y1, float &_x, float &_y) {
    if (x0 == x1) { // if it's a vertical edge
        _x = x0;
        _y = sy + (x0 - sx) * (ey - sy) / (ex - sx);
    }
    else { // if it's a horizontal edge
        _y = y0;
        _x = sx + (y0 - sy) * (ex - sx) / (ey - sy);
    }
}

如果我不得不猜测我会说这是我的内部功能的一个问题,但这就提出了一个问题,为什么它只是不适用于明星而不适用于其他形状?我尝试重写内部函数,但它通常只在不同的方向上导致相同类型的错误。如果有人能指出我正确的方向,我会很感激。

0 个答案:

没有答案