2012-09-24 34 views
-1

实施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; 
} 
+0

你真的调试过那个intersection()方法吗?它看起来很错误... – SinisterMJ

+0

-1代码巨大的墙壁和“调试plix”。 – Puppy

回答

1

你有一个内存错误跺脚 - 你写的pointList阵列无效的指数,该指数覆盖的内存随即。您的原始代码恰好工作,因为它之后的内存未被使用,但是当您切换声明的顺序时,内存跺脚会覆盖变量numberOfVertices

我建议用Valgrind的运行程序,以发现其中的内存跺脚发生。

1

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] = { ... }; 

有足够的空间。