如何使用 std::sort 循环结构中的一个变量并重新排列另一个变量?

问题描述 投票:0回答:1

老实说,我不知道为什么我的问题被称为重复问题,因为所有其他示例都显示了如何对结构中的变量进行排序。我试图根据另一个结构对结构中的变量进行排序,但我找不到示例。以下是我的问题,希望有人能帮忙:

我有一个为学习而开发的基本粒子系统。

我的主要粒子包含在一个如下所示的结构中:

struct Particle {
float px;  // x-position
float py;  // y-position
float pz;  // z-position
float scale;
float rotation;
float red;
float green;
float blue;
float alpha;
int index; };

Index 是粒子 ID。当我创建每个新粒子时,它会保存到名为

std::vector<Particle> particles;
的粒子向量数组中,我将其递增 1。最后,我画了它们。

我现在想引入一个深度排序的过程,这样我就可以从最远到最近绘制粒子。

我知道 std::sort 会起作用。我的理解是,我需要循环遍历 keywords.pz (z 位置),但将该排序结果应用于 keywords.index。因此索引最终将被重新排列并保持正确的绘制顺序。我已经完成了这项工作,但没有使用 std::sort 并且速度非常慢。因此,我希望 std::sort 能够提高性能。

我发现要做到这一点,你可以像这样对结构进行排序:

    std::sort(particles.begin(), particles.end(), [](const auto& lhs, const auto& rhs)
        {
            return lhs.pz1 > rhs.pz1;
        });

但这会重新排列 z 位置,而我想根据 z 位置排序重新排列粒子索引。我看过很多其他例子,但似乎没有一个解决这个问题。

我对结构没有那么丰富的经验,更不用说排序了,所以显然我做错了。

如何修改此代码,以便它按从最远到最近的顺序对粒子 z 位置进行排序,并将该排序应用于粒子索引?

附录:

也许这会有所帮助。此代码显示了我当前的排序算法及其工作原理。我正在尝试优化它,看看 std::sort 是否可以表现得更好。这是在我使用结构之前,因此变量的命名不同,我希望我正确复制了它,但这主要是为了说明目的。 (计数器为总粒子数)。

            for (int i = 0; i < counter - 1; ++i) {
            for (int j = 0; j < counter - 1; ++j) {
                int p = particles[j].index;
                int q = particles[j + 1].index;

                if ( particles[p].pz > particles[q].pz) {
                    unsigned int tmp = particles[j].index;
                    particles[j].index = particles[j + 1].index;
                    particles[j + 1].index = tmp;

                }
            }
        }

结论:

@PaulMcKenzie 能够帮助我理解并解决这个问题。他付出了额外的努力写出了示例代码,我将在下面发布它作为我接受的答案。在进行一些小的调整后,我可以确认他的解决方案有效并且速度更快。我的测试需要 16 秒的计算时间,而他使用 std::sort 的解决方案将其缩短到 3.8 秒。再次感谢!

#include <algorithm>
#include <vector>
#include <numeric>
#include <iostream>
#include <random>

struct Particle {
float px;  // x-position
float py;  // y-position
float pz;  // z-position
float scale;
float rotation;
float red;
float green;
float blue;
float alpha;
};

int main()
{
    // random number generator
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_real_distribution<float> zValues(1.0f, 1000.0f);
   
    // Fill vector with random z values
    std::vector<Particle> vParticles(10);
    for (auto& v : vParticles )
       v.pz = zValues(gen);

    std::vector<int> index(10);
    std::cout << "Original order by z:\n";
    for (auto& v : vParticles)        
      std::cout << v.pz << "\n";

    // set up index array
    std::iota(index.begin(), index.end(), 0);

    // Sort via the index
    std::sort(index.begin(), index.end(), [&](int n1, int n2) 
        { return vParticles[n1].pz < vParticles[n2].pz;});

    std::cout << "\nSorted order by z:\n";
    for (auto& i : index)        
      std::cout << vParticles[i].pz << " " << " is at index " << i << "\n";

    std::cout << "\nHere is the final index array:\n";
    for (auto& i : index)        
        std::cout << i << "\n";

    std::cout << "\nProof that vector has not changed:\n";
    for (auto& v : vParticles)        
      std::cout << v.pz << "\n";
}
c++ sorting optimization particles particle-system
1个回答
0
投票

@PaulMcKenzie 能够帮助我理解并解决这个问题。他付出了额外的努力写出了示例代码,我将在下面发布它作为我接受的答案。在进行一些小的调整后,我可以确认他的解决方案有效并且速度更快。我的测试需要 16 秒的计算时间,而他使用 std::sort 的解决方案将其缩短到 3.8 秒。再次感谢!

#include <algorithm>
#include <vector>
#include <numeric>
#include <iostream>
#include <random>

struct Particle {
float px;  // x-position
float py;  // y-position
float pz;  // z-position
float scale;
float rotation;
float red;
float green;
float blue;
float alpha;
};

int main()
{
    // random number generator
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_real_distribution<float> zValues(1.0f, 1000.0f);
   
    // Fill vector with random z values
    std::vector<Particle> vParticles(10);
    for (auto& v : vParticles )
       v.pz = zValues(gen);

    std::vector<int> index(10);
    std::cout << "Original order by z:\n";
    for (auto& v : vParticles)        
      std::cout << v.pz << "\n";

    // set up index array
    std::iota(index.begin(), index.end(), 0);

    // Sort via the index
    std::sort(index.begin(), index.end(), [&](int n1, int n2) 
        { return vParticles[n1].pz < vParticles[n2].pz;});

    std::cout << "\nSorted order by z:\n";
    for (auto& i : index)        
      std::cout << vParticles[i].pz << " " << " is at index " << i << "\n";

    std::cout << "\nHere is the final index array:\n";
    for (auto& i : index)        
        std::cout << i << "\n";

    std::cout << "\nProof that vector has not changed:\n";
    for (auto& v : vParticles)        
      std::cout << v.pz << "\n";
}
© www.soinside.com 2019 - 2024. All rights reserved.