更改声明顺序时输出不正确



Sutherland-Hodgeman 多边形裁剪的实现。这两个语句的声明顺序给出了正确的输出,反之则不然。

int numberOfVertices = 5;
Point pointList[] = { {50,50}, {200,300}, {310,110}, {130,90}, {70,40} };

转声明时出现的确切错误是底部裁剪器生成一组空顶点,因此裁剪后不显示多边形。

此错误的原因是什么?

法典:

#include <iostream>
#include <GL/glut.h>
#define MAXVERTICES 10
#define LEFT 0
#define RIGHT 1
#define TOP 2
#define BOTTOM 3
using namespace std;
/* Clipping window */
struct Window {
    double xmin;
    double xmax;
    double ymin;
    double ymax;
};
struct Point {
    double x;
    double y;
};
/* If I interchange these two lines, the code doesn't work. */
/**************/
int numberOfVertices = 5;
Point pointList[] = { {50,50}, {200,300}, {310,110}, {130,90}, {70,40} };
/**************/
const Window w = { 100, 400, 60, 200 };
/* Checks whether a point is inside or outside a window side */
int isInside(Point p, int side) {
    switch(side) {
        case LEFT:
            return p.x >= w.xmin;
        case RIGHT:
            return p.x <= w.xmax;
        case TOP:
            return p.y <= w.ymax;
        case BOTTOM:
            return p.y >= w.ymin;
    }
}
/* Calculates intersection of a segment and a window side */
Point intersection(Point p1, Point p2, int side) {
    Point temp;
    double slope, intercept;
    bool infinite;
    /* Find slope and intercept of segment, taking care of inf slope */
    if(p2.x - p1.x != 0) {
       slope = (p2.y - p1.y) / (p2.x - p1.x);
       infinite = false;
    } else {
        infinite = true;
    }
    intercept = p1.y - p1.x * slope;
    /* Calculate intersections */
    switch(side) {
        case LEFT:
            temp.x = w.xmin;
            temp.y = temp.x * slope + intercept;
            break;
        case RIGHT:
            temp.x = w.xmax;
            temp.y = temp.x * slope + intercept;
            break;
        case TOP:
            temp.y = w.ymax;
            temp.x = infinite ? p1.x : (temp.y - intercept) / slope;
            break;
        case BOTTOM:
            temp.y = w.ymin;
            temp.x = infinite ? p1.x : (temp.y - intercept) / slope;
            break;
    }
    return temp;
}
/* Clips polygon against a side, updating the point list
(called once for each side) */
void clipAgainstSide(int sideToClip) {
    int i, j=0;
    Point s,p;
    Point outputList[MAXVERTICES];
    /* Main algorithm */
    s = pointList[numberOfVertices-1];
    for(i=0 ; i<numberOfVertices ; i++) {
        p = pointList[i];
        if(isInside(p, sideToClip)) {
            /* p inside */
            if(!isInside(s, sideToClip)) {
                /* p inside, s outside */
                outputList[j] = intersection(p, s, sideToClip);
                j++;
            }
            outputList[j] = p;
            j++;
        }
        else if(isInside(s, sideToClip)) {
            /* s inside, p outside */
            outputList[j] = intersection(s, p, sideToClip);
            j++;
        }
        s = p;
    }
    /* Updating number of points and point list */
    numberOfVertices = j;
    /* ERROR: In last call with BOTTOM argument, numberOfVertices becomes 0 */
/* all earlier 3 calls have correct output */
    cout<<numberOfVertices<<endl;
    for(i=0 ; i<numberOfVertices ; i++) {
        pointList[i] = outputList[i];
    }
}
void SutherlandHodgemanPolygonClip() {    
    clipAgainstSide(LEFT);
    clipAgainstSide(RIGHT);
    clipAgainstSide(TOP);
    clipAgainstSide(BOTTOM);
}
void init() {
    glClearColor(1,1,1,0);
    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(0,1000,0,500);
}
void display() {
    glClear(GL_COLOR_BUFFER_BIT);
    /* Displaying ORIGINAL box and polygon */
    glColor3f(0,0,1);
    glBegin(GL_LINE_LOOP);
        glVertex2i(w.xmin, w.ymin);
        glVertex2i(w.xmin, w.ymax);
        glVertex2i(w.xmax, w.ymax);
        glVertex2i(w.xmax, w.ymin);
    glEnd();
    glColor3f(1,0,0);
    glBegin(GL_LINE_LOOP);
        for(int i=0 ; i<numberOfVertices ; i++) {
            glVertex2i(pointList[i].x, pointList[i].y);
        }
    glEnd();
    /* Clipping */
    SutherlandHodgemanPolygonClip();
    /* Displaying CLIPPED box and polygon, 500px right */
    glColor3f(0,0,1);
    glBegin(GL_LINE_LOOP);
        glVertex2i(w.xmin+500, w.ymin);
        glVertex2i(w.xmin+500, w.ymax);
        glVertex2i(w.xmax+500, w.ymax);
        glVertex2i(w.xmax+500, w.ymin);
    glEnd();
    glColor3f(1,0,0);
    glBegin(GL_LINE_LOOP);
        for(int i=0 ; i<numberOfVertices ; i++) {
            glVertex2i(pointList[i].x+500, pointList[i].y);
        }
    glEnd();
    glFlush();
}
int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(1000,500);
    glutCreateWindow("Sutherland-Hodgeman polygon clipping");
    init();
    glutDisplayFunc(display);
    glutMainLoop();
    return 0;
}

你有一个内存踩踏错误 - 你正在使用无效索引写入pointList数组,然后立即覆盖内存。 你的原始代码恰好有效,因为后面的内存没有被使用,但是当你切换声明的顺序时,内存踩踏会覆盖变量numberOfVertices

我建议使用 Valgrind 运行您的程序以查找内存踩踏发生的位置。

in

    if(isInside(p, sideToClip)) {
        /* p inside */
        if(!isInside(s, sideToClip)) {
            /* p inside, s outside */
            outputList[j] = intersection(p, s, sideToClip);
            j++;
        }
        outputList[j] = p;
        j++;
    }
    else if(isInside(s, sideToClip)) {
    }
    s = p;
}
/* Updating number of points and point list */
numberOfVertices = j;
for(i=0 ; i<numberOfVertices ; i++) {
    pointList[i] = outputList[i];
}

您可以增加numberOfVertices,但pointList只有初始点的空间。声明它

Point pointList[MAXVERTICES] = { ... };

有足够的空间。

相关内容

  • 没有找到相关文章

最新更新