Векторные частицы с вложенными петлями — столкновения не обнаружены

Поэтому у меня есть частицы (эллипсы), прыгающие по экрану. Я пытаюсь заставить их столкнуться, а не обгонять друг друга. Чтобы сделать это, я должен пройтись по каждой частице и сравнить ее расстояние с каждой другой частицей с циклом for, вложенным в другой цикл for, а затем сказать, что их скорость изменяется, когда их точки находятся на определенном расстоянии друг от друга, вот так:

//p.size() returns the size of the particle system (yes it works)
//ofDist() is an open frameworks function that calculates the dist between 2 points

for( int i = 0; i < p.size(); i++){
//        cout << i << endl;
for(int j = 0; j < p.size(); j++){
//            cout << j << endl;
pDist[i] = ofDist(p[i].pos.x, p[i].pos.y, p[j].pos.x, p[j].pos.y);
//            cout << pDist[i] << endl;
if(pDist[i] <= 300){
p[i].vel.x *= -1;
p[i].vel.y *= -1;
p[j].vel.x *= -1;
p[j].vel.y *= -1;
}
}
}

Но по какой-то таинственной причине они все еще проходят прямо друг над другом, как будто их даже не существует. Это делает работать, если я применю это только к двум частицам без циклов for:

    pDist[0] = ofDist(p[0].pos.x, p[0].pos.y, p[1].pos.x, p[1].pos.y);

if(pDist[0] <= 300){
cout << "It's colliding" << endl;
p[0].vel.x *= -1;
p[0].vel.y *= -1;
p[1].vel.x *= -1;
p[1].vel.y *= -1;
}

Кстати, частицы хранятся в векторе.

Любые идеи, как я могу заставить это работать с циклами for?

Обновить
Размер моего вектора равен 3, поэтому p.size() = 3 (или 2, на самом деле не имеет значения сейчас). Я подставил p.size() для 2 и 3 в моем коде, и это ничего не изменило, так что это не источник проблемы.

обновление 2
Если бы кто-то мог дать мне знать, что мне нужно сделать, чтобы не быть опущенным, это было бы полезно. : /

0

Решение

Довольно большая проблема заключается в том, что, говоря:

for( int i = 0; i < p.size(); i++){
for(int j = 0; j < p.size(); j++){

Вы фактически проверяете каждую частицу против себя. Вы также дважды проверяете столкновение частиц. Обнаружив одно столкновение дважды и инвертируя скорость каждый раз, вы практически ничего не делаете (a * -1 * -1 = a).

Лучший способ сделать это — использовать цикл, в котором столкновения частиц проверяются только один раз, а частица не проверяется сама. Вы можете сделать это, запустив вложенный цикл после текущей частицы (по существу, сместив индекс на уже проверенные индексы), например, так:

for( int i = 0; i < p.size()-1; i++){
for(int j = i+1; j < p.size(); j++){

Это также имеет преимущество в том, что значительно быстрее для большего числа частиц.

Также нет причин хранить рассчитанное расстояние в массиве (если ваш код не использует это где-то еще). Простое использование двойного будет хорошо работать здесь.

Редактировать:

Просто чтобы быть немного яснее, я записал выходные данные двух массивов для демонстрации. Я использовал 3 частицы в массиве.

Оригинальная петля

1 по сравнению с 1 (это проблема. Проверка частицы на себя)

1 по сравнению с 2

1 по сравнению с 3

2 по сравнению с 1 (это проблема. Это уже проверено)

2 по сравнению с 2 (это проблема. Проверка частицы против себя)

2 по сравнению с 3

3 по сравнению с 1 (это проблема. Это уже проверено)

3 по сравнению с 2 (это проблема. Это уже проверено)

3 по сравнению с 3 (это проблема. Проверка частицы на себя)

Модифицированный цикл

1 по сравнению с 2

1 по сравнению с 3

2 по сравнению с 3

Как видите, в модифицированном цикле проверены только три коллизии, и двойных взлетов нет.

2

Другие решения


По вопросам рекламы [email protected]