-4

我是 C++ 编程的新手,并试图让一些 boids 都移到中心,我有两种方法 updateboid 和 cohesion。在凝聚力中,我试图将归一化向量返回到 updateBoid,当我这样做时,boids 只是全部侧向移动,而不是向中心移动。我在这里做一些愚蠢的事情,我们将不胜感激。

void Scene::updateBoid()
{
    for(size_t i=0; i<m_collection.size(); ++i)
    {
        for(auto &m :m_collection[i])
        {
            m->acc = cohesion();

            m->pos += m->acc * 0.05f ;
        }
    }
}


Vec3 Scene::cohesion()
{
    const float pi = 3.14f;

    Vec3 center;
    Vec3 test;

    for(size_t i=0; i<m_collection.size(); ++i)
    {
        for(auto _m :m_collection[i]) // all of the boids
        {
            center += _m->pos;
        }

        center /= m_collection[i].size(); // doing this gives the center

        /// Boids move to the center of their average positions
        for(auto &m :m_collection[i])
        {
            m->dir =center - m->pos; //vector between the two objects

            m->dir.normalize();

            return m->dir;
        }
    }

}

cohesion() 中的先前代码

        m->dir =center - m->pos;        //length between the two objects
        m->dir.normalize();
        m->pos+=m->dir * 0.25f; //speed

这行得通,但希望通过使用另一种方法来更新另一种方法。

4

2 回答 2

0

cohesion您在每次调用中总是返回(基本上)相同的方向,因此您将所有设置m->acc为相同的值。那是因为您的returnincohesion已经退出了第一个 boid。

问题是你还没有下定决心cohesion应该做什么。如果它应该返回一个boid 的目标方向,那么你必须告诉它要考虑哪个boid。您也可以m->acc直接更新cohesion并留下updateBoid修改m->pos(并且只阅读m->acc- 这可能是更好的解决方案。

在代码中:


选项 1:不返回任何东西。只修改每个 boid。不要cohesion在里面打电话updateBoid,就一次。

void Scene::updateBoid()
{
    for(size_t i=0; i<m_collection.size(); ++i)
    {
        for(auto &m :m_collection[i])
        {
            float acc = m->dir;
            m->pos += acc * 0.05f;
        }
    }
}


void Scene::updateCohesion()
{
    for(size_t i=0; i<m_collection.size(); ++i)
    {
        // This must be in here, otherwise it will be slightly wrong later.
        Vec3 center;

        for(auto _m :m_collection[i]) // all of the boids
        {
            center += _m->pos;
        }

        center /= m_collection[i].size(); // doing this gives the center

        /// Boids move to the center of their average positions
        for(auto &m :m_collection[i])
        {
            m->dir =center - m->pos; //vector between the two objects

            m->dir.normalize();
        }
    }
}

选项 2:返回每个 boid 的方向。这是低效的,因为您每次都要重新计算中心。

void Scene::updateBoid()
{
    for(size_t i=0; i<m_collection.size(); ++i)
    {
        for(auto &m :m_collection[i])
        {
            float acc = cohesionForBoid(m_collection[i], m);
            m->pos += acc * 0.05f;
        }
    }
}

// What are these types? We don't know, that is missing from the question.
Vec3 Scene::cohesionForBoid(??? collection, ??? m)
{
    Vec3 center;

    for(auto _m : collection) // all of the boids
    {
        center += _m->pos;
    }

    center /= collection.size(); // doing this gives the center

    Vec3 dir = center - m->pos; //vector between the two objects
    dir.normalize();
    return dir;
}
于 2018-12-17T16:56:42.697 回答
0
for(auto &m :m_collection[i])
{
    m->dir =center - m->pos; //vector between the two objects
    m->dir.normalize();
    return m->dir; // <- Always return on the first iteration
}

正如 Max Langhof 已经指出的那样,for 循环只会执行一次。我称之为错误。从修改代码开始。

于 2018-12-17T17:23:52.617 回答