Не могу остановить выброс частиц

Я пытаюсь создать простую симуляцию частиц. Есть два типа частиц: статические и движущиеся. Статические частицы притягивают движущиеся частицы к своему центру. У статических частиц есть атрибут силы, который определяет, насколько сильно они притягивают движущиеся частицы.

var angle:Number = Math.atan2(moving.y - static.y , moving.x - static.x);
var dist = Point.distance(new Point(moving.x,moving.y) , new Point(static.x,static.y));

moving.velX += Math.cos(angle + Math.PI) * static.strength / dist;
moving.velY += Math.sin(angle + Math.PI) * static.strength / dist;

Проблема заключается в том, что когда частица просто проходит через центр, расстояние очень мало, что приводит к очень большим значениям скорости.

Я добавил дополнительную проверку расстояния перед вычислением скорости.

if (dist < 1)
    dist = 1;

Но проблема все еще сохраняется. Я не могу понять проблему.

Вот снимок происходящего перерегулирования.

введите здесь описание изображения


person Sayam Qazi    schedule 04.07.2016    source источник


Ответы (2)


Обычные силовые поля используют квадрат расстояния в качестве модификатора, здесь вы используете одиночную степень расстояния, конечно, силовое поле работает по-другому. Вы должны изменить строку var dist на следующую:

var dist:Number = (moving.x-static.x)*(moving.x-static.x) + (moving.y-static.y)*(moving.y-static.y);

Таким образом, dist будет содержать квадрат фактического расстояния, поэтому деление на dist даст вам правильную конфигурацию силового поля.

И, пожалуйста, переименуйте static, так как это зарезервированное слово в AS3.

person Vesper    schedule 04.07.2016
comment
Я не использовал «статический» в качестве имени переменной в своем исходном коде. - person Sayam Qazi; 04.07.2016
comment
@SayamQazi, проверьте свой код, у вас есть static.x и static.y. Назовите его force, назовите его atttractor или как-то еще, только не имена переменных или классов, которые меняются на тот же цвет, что и зарезервированные слова. - person VC.One; 04.07.2016
comment
Да, я знаю. Я говорил о своем исходном коде. Я не копировал свой исходный код здесь, на SO. - person Sayam Qazi; 04.07.2016

Вероятно, вы объявляете это значение dist перед выполнением вычисления dist или после выполнения вычисления vel. Вместо этого убедитесь, что выполняемая вами проверка расстояния находится между вычислением dist и вычислением vel. Веспер также прав в том, что для получения правильного эффекта силы он должен использовать квадрат расстояния. Но даже делая это, вы все равно можете получить нежелательные (хотя и абсолютно точные, математически) результаты.

var angle:Number = Math.atan2(moving.y - static.y , moving.x - static.x);
var dist = Point.distance(new Point(moving.x,moving.y) , new Point(static.x,static.y));

if (dist < 1) dist = 1; // just make sure your constraint goes here.

moving.velX += Math.cos(angle + Math.PI) * static.strength / dist / dist; // this uses dist squared
moving.velY += Math.sin(angle + Math.PI) * static.strength / dist / dist; // but don't use this method in addition to Vesper's or you'll have dist to the power of 4. 
person Neal Davis    schedule 04.07.2016
comment
Да, у меня есть проверка расстояния между расчетом расстояния и обновлением скорости. Вы говорите, что я все еще могу получить нежелательные результаты, поэтому не могли бы вы предложить мне решение. - person Sayam Qazi; 04.07.2016
comment
Судя по всему, Веспер решил вашу проблему. Можешь просто проигнорировать мой совет. Или его решение не сработало? - person Neal Davis; 04.07.2016