gpt4 book ai didi

sorting - 如何分类对象以进行Guendelman激波传播?

转载 作者:行者123 更新时间:2023-12-02 04:00:13 24 4
gpt4 key购买 nike

这是关于以3D形式形成地形树的问题。有一点背景:我有一个物理引擎,其中有物体,碰撞点和一些约束。这不是家庭作业,而是多线程实验。

我需要按照从下到上的方式对主体进行排序,并按照本文档所述的方式将属于各层的对象分组:请参阅“冲击传播”部分
http://www2.imm.dtu.dk/visiondag/VD05/graphical/slides/kenny.pdf

他用来描述如何遍历树的伪代码非常合理:

shock-propagation(algorithm A)
compute contact graph
for each stack layer in bottom up order
fixate bottom-most objects of layer
apply algorithm A to layer
un-fixate bottom-most objects of layer
next layer

我已经弄清楚算法A(我的脉冲代码)。 带有3D点列表的树/层排序(拓扑排序?)的伪代码是什么样的?

即,我不知道在下一个“行”或“分支”处停止/开始的位置。我想我可以按y位置将其分块,但这似乎很笨拙且容易出错。我是否研究 topographical sorting?我真的不知道如何在3D模式下进行此操作。如果这样做的话,如何获得拓扑分类的“优势”?

我是否在考虑这个问题,而只是通过找到点p1然后找到最远的下一个点p2来“连接点”,其中p2.y> p1.y?我在这里看到一个问题,其中使用纯距离到p0的p1距离可能大于p2,这将导致错误的排序。

最佳答案

我自己解决了这个问题。

我在链接到本文的可下载源代码中找到了一个如何实现此目的的示例:

http://www-cs-students.stanford.edu/~eparker/files/PhysicsEngine/

特别是WorldState.cs文件从221行开始。

但是这样的想法是,您为所有静态对象分配了-1级别,并且为每个其他对象分配了不同的默认级别,例如-2。然后,对于与级别-1的物体的每次碰撞,请将其碰撞的物体添加到列表中,并将其等级设置为0。

之后,使用while循环while(list.Count> 0)检查与之碰撞的物体,并将那里的物体的水平设置为body.level +1。

之后,对于模拟中仍具有默认级别(我之前说过-2)的每个主体,将其级别设置为最高级别。

还有一些更好的细节,但是查看示例中的代码将比我能更好地解释它。

希望能帮助到你!

Evan Parker的代码中的相关代码。 [斯坦福大学]

{{{

// topological sort (bfs)
// TODO check this
int max_level = -1;
while (queue.Count > 0)
{
RigidBody a = queue.Dequeue() as RigidBody;
//Console.Out.WriteLine("considering collisions with '{0}'", a.Name);
if (a.level > max_level) max_level = a.level;
foreach (CollisionPair cp in a.collisions)
{
RigidBody b = (cp.body[0] == a ? cp.body[1] : cp.body[0]);
//Console.Out.WriteLine("considering collision between '{0}' and '{1}'", a.Name, b.Name);
if (!b.levelSet)
{
b.level = a.level + 1;
b.levelSet = true;
queue.Enqueue(b);
//Console.Out.WriteLine("found body '{0}' in level {1}", b.Name, b.level);
}
}
}

int num_levels = max_level + 1;

//Console.WriteLine("num_levels = {0}", num_levels);

ArrayList[] bodiesAtLevel = new ArrayList[num_levels];
ArrayList[] collisionsAtLevel = new ArrayList[num_levels];
for (int i = 0; i < num_levels; i++)
{
bodiesAtLevel[i] = new ArrayList();
collisionsAtLevel[i] = new ArrayList();
}

for (int i = 0; i < bodies.GetNumBodies(); i++)
{
RigidBody a = bodies.GetBody(i);
if (!a.levelSet || a.level < 0) continue; // either a static body or no contacts

// add a to a's level
bodiesAtLevel[a.level].Add(a);

// add collisions involving a to a's level
foreach (CollisionPair cp in a.collisions)
{
RigidBody b = (cp.body[0] == a ? cp.body[1] : cp.body[0]);
if (b.level <= a.level) // contact with object at or below the same level as a
{
// make sure not to add duplicate collisions
bool found = false;
foreach (CollisionPair cp2 in collisionsAtLevel[a.level])
if (cp == cp2) found = true;

if (!found) collisionsAtLevel[a.level].Add(cp);
}
}
}

for (int step = 0; step < num_contact_steps; step++)
{
for (int level = 0; level < num_levels; level++)
{
// process all contacts
foreach (CollisionPair cp in collisionsAtLevel[level])
{
cp.ResolveContact(dt, (num_contact_steps - step - 1) * -1.0f/num_contact_steps);
}
}
}

}}}

关于sorting - 如何分类对象以进行Guendelman激波传播?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10858871/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com