调试多边形近似算法代码C ++

时间:2012-11-26 08:11:56

标签: c++ algorithm debugging opengl polygon

我想知道你是否有可能帮我调试我的一些代码。我为类项目编写了以下代码,我们正在实现一个多边形近似算法。但我似乎无法让代码完成我想做的事情。以下是该算法的wiki文章的链接:http://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm

我遇到的问题是第二个数组,closedStack要么没有正确更新内部值,要么它没有正确显示。但第一个数组,从文件中读入的数组正确显示。我也一直收到closedStack错误,因为我将if语句更改为不使用fileSize变量,因此也可能存在问题。如果你需要我解释任何逻辑或变量等,请问我,我会解释。

#include "math.h"
#include <iostream>
#include <fstream>
#include "glut.h"

using namespace std;

struct point{
    int x, y;
};

void display(void);
void fileRead();
void oPush(point);
void cPush(point);
point oPop();
int deviation();

point pixel[2000];
int fileSize = 0;
int errorAllowed= 5;
int errorDeviation=0;
int oTop = 0;
int cTop = 0;
point first;
point last;
point openStack[5000];
point closedStack[5000];
int V1 = 0;
int V2 = 0;

void main(int argc, char **argv){

    fileRead();

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(75,75);
    glutCreateWindow("Ramer's Iterative Algorithm");
    glutDisplayFunc(display);
    gluOrtho2D(0,500,0,500);

    fileSize = fileSize/2;

    int tmp1 = pixel[0].x+pixel[0].y;
    int tmp2 = 0;


    for(int i = 0; i<2000; i++){
        tmp2 = pixel[i].x+pixel[i].y;

        if(tmp2 < tmp1){
            tmp1 = tmp2;
            V1 = i;
        }
    }

    for(int i = 0; i<2000; i++){
        tmp2 = pixel[i].x+pixel[i].y;

        if(tmp2 > tmp1){
            tmp1 = tmp2;
            V2 = i;
        }
    }

    oPush(pixel[V1]);
    oPush(pixel[V2]);
    oPush(pixel[V1]);

    do{
        first = oPop();
        last = oPop();

        int Mid = deviation();

        if(errorDeviation>errorAllowed){
            oPush(last);
            oPush(pixel[Mid]);
            oPush(first);
        }

        else if(errorDeviation<=errorAllowed){
            oPush(last);
            cPush(first);
        }

    }while(oTop>=2);

    glutMainLoop();

    cin >> V1;

}

void display(void){
    glClearColor(0,0,0,0);
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1,1,1);

    glBegin(GL_POINTS);
    for(int i=0; i<2000; i++)
        glVertex2i(pixel[i].x,pixel[i].y);
    glEnd();

    glColor3f(1,0,0);
    glBegin(GL_LINE_STRIP);
    for(int i=0;i<=cTop; i++)
        glVertex2i(closedStack[i].x,closedStack[i].y);
    glEnd();

    glFlush();
}

void fileRead(){
    char fileName[20];

    cout << "Enter the name of the file you would like to parse data from: ";
    cin >> fileName;

    ifstream boundary;
    boundary.open(fileName);
    if(boundary.fail()){
        cout << "Could not open '" << fileName << "' for reading.\n";
        exit(0);
    }

    for(int i=0; !boundary.eof(); i++){
        boundary >> pixel[i].x;
        boundary >> pixel[i].y;
        fileSize ++;
    }

}

void oPush(point p){
    if(oTop>fileSize){
        cout << "Full Stack--Open\n";
        exit(0);
    }

    else{
        oTop++;
        openStack[oTop]= p;
    }
}

void cPush(point p){
    if(cTop>10000){
        cout << "Full Stack--Closed\n";
        exit(0);
    }

    else{
        cTop++;
        closedStack[cTop]= p;
    }
}

point oPop(){
    point temp;

    if(oTop<=0){
        cout << "Stack Empty\n";
        exit(0);
    }

    else{
        temp = pixel[oTop];
        oTop--;
    }
    return temp;
}

int deviation(){
    float y = last.y-first.y;
    float x = last.x-first.x;
    float theta = atan(y/x);
    int most = 0;

    for(int i = V1+1; i < V2; i++){
        float ped = (-(pixel[i].x-first.x)*sin(theta))+((pixel[i].y-last.y)*cos(theta));
        float errDev= abs(ped);

        if(errDev>most)
            most = i;
        errorDeviation = (int)errDev;
    }

    return most;
}

详细说明V1和V2,它们应该是数组的左下角和右上角。检查我已简化为:

的循环
for(int i = 0; i<fileSize; i++){
tmp2 = (pixel[i].x)+(pixel[i].y);

if(tmp2 <= tmp1){
    tmp1 = tmp2;
    V1 = i;
}

if(tmp2 >= tmp1){
    tmp1 = tmp2;
    V2 = i;
}

循环将点的x + y加在一起,然后将其与前一点进行检查以更新它。最低x + y的点最终应为V1,最高点应为V2。但我不认为循环功能正常。通过放大绘制的内容,显示循环的第二部分只有三个点。它看起来像初始数组的第一个和第二个点以及0,0被绘制。不确定为什么会这样。

1 个答案:

答案 0 :(得分:0)

就目前而言,你的问题实在太宽泛了。你需要尝试自己缩小范围。这是一个很好的清单:http://msmvps.com/blogs/jon_skeet/archive/2012/11/24/stack-overflow-question-checklist.aspx

您不会通过尝试一次性编写完整的工作程序来解决您的问题。视觉输出是无价的,但它不能取代实际的点列表的文本输出。您的问题和评论表明您只是通过查看最终的视觉输出来尝试调试它。您需要将其分解为更小的部分并查看每个步骤之间的数据,以便您可以了解程序偏离预期的位置。

如你所说“第二个数组,closedStack要么没有正确更新内部值,要么它没有正确显示”。解决这个问题的第一步是找出其中的哪一个是这样的!阵列是否具有错误的值,或者是否显示不正确?您可以通过打印出中间值并将它们与您手动解决问题时的预期值进行比较来找到它。如果输入太大,请创建一组较小的输入点,您可以手动操作。一旦你缩小范围,你就会发现你可以自己解决问题,或者你有一个更有针对性的问题要求它能得到更好的答案。


粗略的检查,我猜:

  1. 您似乎很容易误解输入。你还没有描述它是什么。如果它是一个形成piece-wise linear curve的点序列,则不清楚为什么选择最西南和最东北的元素(假设东是+ ve x和北+ ve y)是有帮助的。 。如果它是一堆积分,那么你需要做的不仅仅是选择角落以便以有意义的顺序完成其余的工作。
  2. 您的函数deviation()似乎假设索引第一个小于索引 last 。但似乎没有什么可以保证这一点。首先,也许V1具有比V2更大的索引。即使没有,也用[V1,V2,V1]填充初始堆栈,保证deviation()将看到first&gt;的输入。 last。虽然我当然不能保证deviation()没有任何问题,但我的猜测是你的食物存在问题。