2012-07-01 2 views
0

Я начинаю на физике/симулятора частиц и у меня возникли некоторые проблемы с обнаружением коллизий:силы тяжести и влияние ошибка

http://mmhudson.com/physics.html

Im не столько ищет решения кода, а кто-то, чтобы объяснить вопрос для меня концептуально.

Как это работает, я проверяю, будет ли частица находиться внутри/пересекаться с объектом, когда она будет перемещена дальше. Если это так, множитель силы тяжести меняется на противоположное, поэтому его направление меняется на противоположное.

Уравнение движения я использую это:

Следующее местоположение = текущая скорость + скорость гравитации + текущее местоположение

Где скорость от тяжести умножитель

Надеюсь, кто-то видел вопрос, как это до или желает проверить источник моей страницы.

Любая помощь на всех очень ценится

ответ

2

Нет концептуальное объяснение, но куча случайных наблюдений:

Я бы рекомендовал добавить холст переменные ширины/высоты и сравнивая их с позиции частиц. Прямо сейчас ваши частицы падают, даже если они уходят с холста. Что-то вроде:

if(particles[i][1] > height) 
    particles.splice(i,1); 

newPY < objects[k][2] + objects[k][3] + radius 

действительно странно. Что ты от этого делаешь? Добавление ширины и высоты объектов и радиуса частицы? Если вы удалите эту часть, частицы будут отскакивать от объектов, пока они имеют «импульс».

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


Вы проверяете для частиц на вершине только объекты, но я предполагаю, что «проваливаться» аспект является частью ошибки вы просили о, так что не так уж важно в данный момент:

particles[i][1] < objects[k][1] + objects[k][3] + radius 

Возможно, однако, если вы решили поиграть и уменьшить гравитацию, чтобы частицы вместо этого набрали силу и отскочили от объектов выше.


Что касается переменной objCheck, вы запутать ширину у в последней & & части. Оно должно быть:

mY < objects[i][1] + objects[i][3] + radius 

вместо

mY < objects[i][2] + objects[i][3] + radius 

Прямо сейчас, ваш objCheck не работает.


Также

for(var i=0; i < particles.length; i++) { 
    var clrRadius = 2*radius; 
    canvas.clearRect(particles[i][0]-radius, particles[i][1]-radius, clrRadius, clrRadius); 
} 

лучше

for(var i=0; i < particles.length; i++){ 
    var clrRadius = radius + 4; 
    canvas.clearRect(particles[i][0]-(clrRadius/2), particles[i][1]-(clrRadius/2), clrRadius, clrRadius); 
} 

редактировать: Похоже, вы изменили код, так как я в последний раз проверил, так что выше, не может больше быть актуальны!

редактирование2: добавлено удаление частица. Вот полный цикл тяжести:

for(var i=0; i<particles.length; i++){ 
var clrRadius = 2*radius; 
canvas.clearRect(particles[i][0]-radius, particles[i][1]-radius, clrRadius, clrRadius); 
} 

for(var i=0; i < particles.length; i++){ 
var newPY = particles[i][1] += particles[i][2] + particles[i][3]; 

for(var k=0; k<objects.length; k++){ 
    if(
     //particle 
     particles[i][0] > objects[k][0] - radius && 
     particles[i][0] < objects[k][0] + objects[k][2] + radius && 
     particles[i][1] > objects[k][1] - radius && 
     particles[i][1] < objects[k][1] + objects[k][3] + radius //&& 
    ){ 
      //reverse gravity 
      particles[i][2] = particles[i][2] * -1; 
      particles[i][5] = objects[k][1] - radius; 
    } 
} 


particles[i][2] += particles[i][3]*weight; 
particles[i][1] += particles[i][2]; 

if(particles[i][1] > particles[i][5]) 
    particles[i][1] = particles[i][5]; 

if(particles[i][1] > height) 
    particles.splice(i,1); 
} 

for(var i=0; i <particles.length; i++){ 
canvas.fillStyle = "#000"; 
canvas.beginPath(); 
canvas.arc(particles[i][0], particles[i][1], radius, 0, Math.PI*2, true); 
canvas.closePath(); 
canvas.fill(); 
} 
0

Я бы не использовать гравитационный множитель.

Каждый объект должен выглядеть следующим образом:

var circle = { 
    x: 0, // x position 
    y: 0, // y position 
    dx: 0, // x velocity 
    dy: 0 // y velocity 
} 

Чтобы обновить частицу, умножить скорость (Dx, Dy) на некоторый промежуток времени и добавить к текущей позиции.

Каждый цикл, добавляющий некоторое изменение скорости в результате силы тяжести.

Если вы обнаружите изменение столкновения, скорость так, чтобы круги отражались друг от друга. Примером этого не будет:

// In a collision, simply reverse the direction of movement 
// so the circles move away from each other. 

function onCollision(circleA, circleB) { 
    circleA.dx *= -1; 
    circleA.dy *= -1; 

    circleB.dx *= -1; 
    circleB.dy *= -1; 
} 
+0

это не исправило бы мою проблему. проблема связана с обнаружением столкновения – maxhud

Смежные вопросы