C++向量在递归函数中丢失数据

发布于 2025-01-06 19:33:57 字数 3946 浏览 0 评论 0原文

我对 C++ 非常陌生,我正在尝试实现一个 TriangleDynamic 对象,该对象可以使用名为 splitTriangleProject 的函数递归地分割自身。它将自身分成四个较小的 TriangleDynamic 对象(并将新三角形的顶点投影到具有给定半径和原点的球体上,但我认为这不是重点),将新创建的三角形推入一个向量,该向量是原始对象的成员数据。向量成员数据称为子三角形。然后,每个子三角形都会调用 splitTriangleProject 函数,直到发生特定“级别”的分割。

我遇到的问题是,只有第一级分割实际上正确地推入了子三角形向量。我确信问题与向量超出范围有关,或者可能与 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();
        }
    }
}

这是我在 main 中调用它的方式:

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

我想我在这一点上发布了太多。感谢任何帮助,提前致谢。

I am very new to C++ and I am trying to implement a TriangleDynamic object that can recursively split itself using a function called splitTriangleProject. It splits itself into four smaller TriangleDynamic objects (and projects the vertices of the new triangles onto a sphere with a given radius and origin, but I believe this is beside the point), pushes the newly created triangles into a vector that is part of the member data of the original object. The vector member data is called subTriangles. Then each subTriangle recalls the splitTriangleProject function until a certain "level" of splits has occurred.

The issue I am having is that only the first level of splitting is actually properly pushing to the subTriangles vector. I am certain that the issue has to do with the vectors going out of scope, or maybe the TriangleDynamic going out of scope. I imagine there is some solution with pointers. If anyone could help, it would be much appreciated.

Here is my TriangleDynamic declaration:

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;

and the constructors:

// 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;
}

Here is my splitTriangleProject function:

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);
    }
}

Here is a function for recursively printing the triangleDynamic when it's done:

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();
        }
    }
}

Here is how I call it in my main:

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

I think I've posted too much at this point. Any help is appreciated, thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

恍梦境° 2025-01-13 19:33:57

问题就在这里,

    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);

请注意在调用 splitTrangleProject 之前如何将三角形的副本推入 subTriangles 向量。

因此,向量中的三角形没有调用 splitTriangleProject。

将推回移到代码末尾,它应该可以工作。

    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 可以大大加快速度。除非必须,否则不要使用指针。)

The issue is right here

    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);

Note how you push a copy of the triangle into the subTriangles vector before you call splitTrangleProject.

Thus the triangles in the vector did not have splitTriangleProject called on them.

Move the pushbacks to the end of the code and it should work.

    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);

(Also, on another note, if this code starts getting slow it could be greatly sped up with a C++11 std::move. Don't go into pointers unless you have to.)

生活了然无味 2025-01-13 19:33:57

在 splitTriangleProject() 中计算子三角形后,您需要检索它们并将其添加到类自己的列表(子三角形)中。
像这样:

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()”。 (现在你似乎将所有成员变量共享为公共,这不是一个好的做法)

After computing the subtriangles inside splitTriangleProject(), you need to retrieve them and add to the class'es own list (subTriangles).
Like this:

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());

}

Then you need to add an additional access method "const vector& getSubTriangles()". (Right now you seem to share all member variables as public which is not a good practise)

就是爱搞怪 2025-01-13 19:33:57

当您将三角形推回到向量中时,它会推入三角形的副本。然后,您在 t1 到 t4 上递归,但此递归不会影响已推入向量的内容,因为它是副本。

When you push_back a triangle into the vector, it pushes a copy of the triangle. You then recurse on t1 to t4, but this recursion won't affect what has already been pushed into the vector, as it is a copy.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文