Вектор C ++ теряет данные в рекурсивной функции - PullRequest
2 голосов
/ 17 февраля 2012

Я очень новичок в C ++ и пытаюсь реализовать объект TriangleDynamic, который может рекурсивно разделить себя, используя функцию splitTriangleProject.Он разбивается на четыре меньших объекта TriangleDynamic (и проецирует вершины новых треугольников на сферу с заданным радиусом и происхождением, но я считаю, что это не относится к точке), толкает вновь созданные треугольники в вектор, который является частьюданные члена исходного объекта.Данные-члены вектора называются подтреугольниками.Затем каждый subTriangle вызывает функцию splitTriangleProject, пока не произойдет определенный «уровень» разбиений.

Проблема, с которой я столкнулся, заключается в том, что только первый уровень расщепления фактически корректно подталкивает к вектору subTriangles.Я уверен, что проблема связана с векторами, выходящими из области видимости, или, может быть, TriangleDynamic выходит из области видимости.Я думаю, что есть какое-то решение с указателями.Если бы кто-то мог помочь, это было бы очень полезно.

Вот мое объявление TriangleDynamic:

class TriangleDynamic
{
public:
    TriangleDynamic(const Point &P1, const Point &P2, const Point &P3);
    TriangleDynamic();
    ~TriangleDynamic(){}
    void printTriangle();
    void splitTriangleProject( int currentLevel, int maxLevel, const Point &org, double radius);
    void init();
    bool operator<(const TriangleDynamic&);
    bool operator>(const TriangleDynamic&);
    Line edge1;
    Line edge2;
    Line edge3;

    Point p1;
    Point p2;
    Point p3;

    Vect normal;

    bool lowestLevel;

    vector<TriangleDynamic> subTriangles;
    static int numTriangles;
    int triangleId;
};

int TriangleDynamic::numTriangles = 0;

и конструкторы:

// constructor for the TriangleDynamic object
TriangleDynamic::TriangleDynamic(const Point &P1, const Point &P2, const Point &P3)
{
    p1 = P1;
    p2 = P2;
    p3 = P3;
    init();
}

TriangleDynamic::TriangleDynamic()
{
    p1 = Point(0,0,0);
    p2 = Point(0,0,1);
    p3 = Point(0,1,0);
    init();
}

void TriangleDynamic::init()
{
    edge1 = Line(p1,p2);
    edge2 = Line(p2,p3);
    edge3 = Line(p3,p1);

    Vect U = p2.minus( p1);
    Vect V = p3.minus(p1);

    normal = U.cross(V);

    lowestLevel = true;
    triangleId = numTriangles + 1;
    numTriangles = triangleId;
}

Вот моя функция splitTriangleProject:

void TriangleDynamic::splitTriangleProject(int currentLevel, int maxLevel, const Point &org, double radius)
{
    if ( currentLevel < maxLevel)
    {
        lowestLevel = false;
        Point worldOrigin = Point(0,0,0);
        double edge1MidMag = (edge1.midpoint - org).distance(worldOrigin) ;
        double edge2MidMag = (edge2.midpoint - org).distance(worldOrigin) ;
        double edge3MidMag = (edge3.midpoint - org).distance(worldOrigin) ;

        Point newEdge1Mid = (((edge1.midpoint) * radius )/ edge1MidMag) + org;
        Point newEdge2Mid = (((edge2.midpoint) * radius )/ edge2MidMag) + org;
        Point newEdge3Mid = (((edge3.midpoint) * radius )/ edge3MidMag) + org;

        TriangleDynamic t1(p1 , newEdge1Mid , newEdge3Mid);
        subTriangles.push_back(t1);

        TriangleDynamic t2(newEdge1Mid, p2, newEdge2Mid);
        subTriangles.push_back(t2);

        TriangleDynamic t3(newEdge3Mid, newEdge2Mid, p3);
        subTriangles.push_back(t3);

        TriangleDynamic t4(newEdge1Mid, newEdge2Mid, newEdge3Mid);
        subTriangles.push_back(t4);

        t1.splitTriangleProject( currentLevel + 1, maxLevel, org, radius);
        t2.splitTriangleProject( currentLevel + 1, maxLevel, org, radius);
        t3.splitTriangleProject( currentLevel + 1, maxLevel, org, radius); 
        t4.splitTriangleProject( currentLevel + 1, maxLevel, org, radius);
    }
}

Вот функция для рекурсивной печати triangleDynamic, когда это будет сделано:

void TriangleDynamic::printTriangle()
{
    cout<< "p1";
    p1.printPoint();
    cout << "\np2";
    p2.printPoint();
    cout << "\np3";
    p3.printPoint();
    cout << "\n\n";

    if(!lowestLevel)
    {
        int ctr;
        for (ctr=0; ctr<=subTriangles.size()-1; ctr++)
        {
            cout << "subTriangle\n";
            subTriangles[ctr].printTriangle();
        }
    }
}

Вот как я ее называю в моем основном:

int main()
{
    TriangleDynamic t = TriangleDynamic();
    t.splitTriangleProject(0,3,Point(), 1);
    t.printTriangle();
    cin.get();
    return 0;
}

Я думаю, что я опубликовал слишком много на данный момент.Любая помощь приветствуется, спасибо заранее.

Ответы [ 3 ]

1 голос
/ 17 февраля 2012

Вопрос прямо здесь

    TriangleDynamic t1(p1 , newEdge1Mid , newEdge3Mid);
    subTriangles.push_back(t1);

    TriangleDynamic t2(newEdge1Mid, p2, newEdge2Mid);
    subTriangles.push_back(t2);

    TriangleDynamic t3(newEdge3Mid, newEdge2Mid, p3);
    subTriangles.push_back(t3);

    TriangleDynamic t4(newEdge1Mid, newEdge2Mid, newEdge3Mid);
    subTriangles.push_back(t4);

    t1.splitTriangleProject( currentLevel + 1, maxLevel, org, radius);
    t2.splitTriangleProject( currentLevel + 1, maxLevel, org, radius);
    t3.splitTriangleProject( currentLevel + 1, maxLevel, org, radius); 
    t4.splitTriangleProject( currentLevel + 1, maxLevel, org, radius);

Обратите внимание, как вы вставляете копию треугольника в вектор subTriangles перед вызовом splitTrangleProject.

Таким образом, для треугольников в векторе не был вызван splitTriangleProject.

Переместите pushbacks в конец кода, и он должен работать.

    TriangleDynamic t1(p1 , newEdge1Mid , newEdge3Mid);


    TriangleDynamic t2(newEdge1Mid, p2, newEdge2Mid);


    TriangleDynamic t3(newEdge3Mid, newEdge2Mid, p3);


    TriangleDynamic t4(newEdge1Mid, newEdge2Mid, newEdge3Mid);


    t1.splitTriangleProject( currentLevel + 1, maxLevel, org, radius);
    t2.splitTriangleProject( currentLevel + 1, maxLevel, org, radius);
    t3.splitTriangleProject( currentLevel + 1, maxLevel, org, radius); 
    t4.splitTriangleProject( currentLevel + 1, maxLevel, org, radius);

    subTriangles.push_back(t3);
    subTriangles.push_back(t2);
    subTriangles.push_back(t1);
    subTriangles.push_back(t4);

(Также, с другой стороны, если этот код начинает работать медленно, он может быть значительно ускорен с помощью C ++ 11 std :: move. Не входите в указатели, если нет необходимости.)

0 голосов
/ 17 февраля 2012

После вычисления подтреугольников внутри splitTriangleProject () вам необходимо извлечь их и добавить в собственный список класса (subTriangles).Например:

void splitTriangleProject( int currentLevel, int maxLevel, const Point &org, double radius)
{
// your code above

subTriangles.insert(subTriangles.begin(), t1.subTriangles.begin(), t1.subTriangles.end());
subTriangles.insert(subTriangles.begin(), t2.subTriangles.begin(), t2.subTriangles.end());
subTriangles.insert(subTriangles.begin(), t3.subTriangles.begin(), t3.subTriangles.end());
subTriangles.insert(subTriangles.begin(), t4.subTriangles.begin(), t4.subTriangles.end());

}

Затем вам нужно добавить дополнительный метод доступа "const vector & getSubTriangles ()".(Прямо сейчас вы, кажется, делитесь всеми переменными-членами как общедоступными, что не является хорошей практикой)

0 голосов
/ 17 февраля 2012

Когда вы вставляете треугольник в вектор, он выталкивает копию треугольника.Затем вы выполняете рекурсию от t1 до t4, но эта рекурсия не повлияет на то, что уже вставлено в вектор, так как это копия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...