0

私のコードのデバッグを手伝ってもらえないかと思っていました。ポリゴン近似アルゴリズムを実装するクラス プロジェクト用に次のコードを作成しました。しかし、私がやりたいことをコードに実行させることができないようです。アルゴリズムのウィキ記事へのリンクは次のとおりです。http://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm

私が抱えている問題は、2 番目の配列、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 になるはずです。しかし、ループが適切に機能しているとは思いません。描画されたものを拡大すると、表示ループの 2 番目の部分には 3 つのポイントしかありません。初期配列の 1 番目と 2 番目の点と 0,0 がプロットされているように見えます。なぜそれが起こっているのか分かりません。

4

1 に答える 1

0

現状では、あなたの質問は本当に広すぎます。自分で絞り込む努力が必要です。ここに良いチェックリストがあります: http://msmvps.com/blogs/jon_skeet/archive/2012/11/24/stack-overflow-question-checklist.aspx

完全に機能するプログラムを 1 回で作成しようとしても、問題は解決されません。視覚的な出力は非常に貴重ですが、実際のポイント リストのテキスト出力を置き換えることはできません。あなたの質問とコメントは、最終的な視覚的出力を見るだけでこれをデバッグしようとしていることを示唆しています。これを小さな断片に分割し、各ステップ間のデータを調べて、プログラムが期待から逸脱している場所を理解できるようにする必要があります。

あなたが言うように、「2番目の配列であるclosedStackは、内部の値が適切に更新されていないか、適切に表示されていません」。この問題を解決するための最初のステップは、これらのどれが該当するかを調べることです! 配列の値が間違っているか、または正しく表示されていませんか? 中間値を出力し、手で問題を解いたときに予想される値と比較することで、それを見つけることができます。入力が大きすぎる場合は、手動で操作できる小さな入力ポイントのセットを作成します。問題を絞り込むと、自分で問題を解決できるか、より焦点を絞った質問をして、より良い答えを引き出すことができるかがわかります。


大まかな検査から、私は推測します:

  1. 入力を誤解しているようです。あなたはそれが何であるかを説明していません。それが部分的な線形曲線を形成する点のシーケンスである場合、最も南西で最も北東の要素を選択することが役立つ理由が明確ではありません (東が +ve x で北が +ve y であると仮定します)。 . 点群の場合は、コーナーを選択して残りを意味のある順序にするだけでなく、それ以上のことを行う必要があります。
  2. あなたの関数は、 index firstが index lastより小さいとdeviation()仮定しているようです。しかし、これを保証するものはないようです。まず、V1 のインデックスが V2 よりも大きい可能性があります。そうでない場合でも、初期スタックに [V1, V2, V1]を入力し、 >の入力が表示されることを保証します。に何も問題がないことを保証するつもりはありませんが、私の推測では、あなたがフィードしている内容に問題があると思います。deviation()firstlastdeviation()
于 2012-11-26T09:45:50.893 に答える