Поэтому у меня есть частицы (эллипсы), прыгающие по экрану. Я пытаюсь заставить их столкнуться, а не обгонять друг друга. Чтобы сделать это, я должен пройтись по каждой частице и сравнить ее расстояние с каждой другой частицей с циклом 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
Если бы кто-то мог дать мне знать, что мне нужно сделать, чтобы не быть опущенным, это было бы полезно. : /
Довольно большая проблема заключается в том, что, говоря:
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
Как видите, в модифицированном цикле проверены только три коллизии, и двойных взлетов нет.