пытаясь вернуть вектор - PullRequest
0 голосов
/ 17 декабря 2018

Я новичок в программировании на 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

Это сработало, но нужен другой подход с использованием другогоспособ обновления.

Ответы [ 2 ]

0 голосов
/ 17 декабря 2018
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
}

Цикл for будет выполняться только один раз, как уже указывал Макс Лангоф.Я бы назвал это ошибкой.Начните с изменения вашего кода.

0 голосов
/ 17 декабря 2018

Вы всегда возвращаете (в основном) одно и то же направление при каждом вызове cohesion, поэтому вы устанавливаете для всех m->acc одинаковое значение.Это потому, что ваш return in cohesion уже выходит на первый бой.

Проблема в том, что вы не определились с тем, что cohesion должен делать.Если предполагается вернуть целевое направление один boid, то вы должны указать ему , что boid следует учитывать.Вы также можете обновить m->acc непосредственно в cohesion и просто оставить updateBoid, чтобы изменить m->pos (и только читать m->acc - это, вероятно, лучшее решение.

В коде:


Вариант 1: ничего не возвращать. Изменять только каждую единицу. Не вызывать 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: вернуть направление для каждой единицыЭто неэффективно, потому что вы вычисляете центр снова каждый раз.

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