老实说,我不知道为什么我的问题被称为重复问题,因为所有其他示例都显示了如何对结构中的变量进行排序。我试图根据另一个结构对结构中的变量进行排序,但我找不到示例。以下是我的问题,希望有人能帮忙:
我有一个为学习而开发的基本粒子系统。
我的主要粒子包含在一个如下所示的结构中:
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";
}
@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";
}