2013-04-22 2 views
1

У меня есть «магнит» прямо в середине моего холста, и у меня есть объекты, которые добавляются к холсту при щелчке. Затем их притягивают к магниту.HTML5 Canvas - вычислить скорость объекта по отношению к «магниту»

У меня есть X и Y расстояние объектов по отношению друг к другу, в диапазоне от примерно -20 до 20.

Этого вычисления я использую для объектов, чтобы привлечь, который работает, но чем ближе его получает, чем слабее сила, когда она должна быть наоборот, как я могу это сделать?

impulseX = (distanceX/100) 
impulseY = (distanceY/100) 

Примеры:

Distance = 20, speed = 0.05 
Distance = 10, speed = 0.1 
Distance = -20, speed = -0.05 
Distance = -10, speed = -0.1 

Пример того, что я делаю: http://jsfiddle.net/qk8Wk/

Благодаря

+0

Можете ли вы подготовить [скрипку] (http://jsfiddle.net/), пожалуйста ?! – yckart

+0

http://jsfiddle.net/qk8Wk/ – Henryz

+0

http://en.wikipedia.org/wiki/Newton%27s_law_of_universal_gravitation <= – JayC

ответ

6

Ваш импульс должен следовать закону обратных квадратов, т.е.

var distance2 = distanceX * distanceX + distanceY * distanceY; 
var mag = n/distance2; 

, где n - общая постоянная, представляющая силу поля.

Затем импульс должен быть в пропорции к направлении этого импульса:

var theta = Math.atan2(distanceY, distanceX); 
var impulseX = mag * Math.cos(theta); 
var impulseY = mag * Math.sin(theta); 

См http://jsfiddle.net/alnitak/BH5qL/

или, избегая при этом тригонометрические функции (за @JayC)

var norm = Math.sqrt(distance2); 
var impulseX = mag * (distanceX/norm); 
var impulseY = mag * (distanceY/norm); 
+2

Строго говоря, использование математических функций тригонометрических функций не требуется. Если вы дадите некоторое значение 'norm = Math.sqrt (distanceX * distanceX + distanceY * distanceY)', то 'cos (theta)' математически эквивалентно 'distanceX/norm' и аналогично' distanceY/norm' для 'sin (theta) '. Примечание. Я сказал «математически» эквивалент, так как в плавающих точках вы можете получить разные результаты. Но, поскольку значение проходит через меньшее количество операций, я ожидаю, что качество значений будет лучше, если вы вообще избегаете функций триггера. – JayC

+0

@JayC хорошая точка, хотя с помощью триггера, вероятно, легче следовать (изначально). – Alnitak

+0

Отличное решение, отлично работает. Я определенно даже не думал по правильному пути, чтобы придумать то, что я хотел. – Henryz

0

, но чем ближе, тем слабее сила,

Довольно логично, потому что разница становится меньше - поэтому разница/100 становится меньше.

, когда все должно быть наоборот, как я могу это сделать?

Сделать ценность, на которой базируется множитель множителя, увеличивается, а не меньше - f.e.

impulseX = ((20 - distanceX)/100) 
1

как насчет:

var distance = Math.sqrt(distanceX*distanceX + distanceY*distanceY) 
impulseX = 0.1*distanceX/distance 
impulseY = 0.1*distanceY/distance 

или вы можете использовать расстояние^2:

var distance2 = distanceX*distanceX + distanceY*distanceY 
impulseX = 0.1*distanceX/distance2 
impulseY = 0.1*distanceY/distance2 
+0

Вы не учли _direction_ импульса во внимание – Alnitak

+0

, вы правы, я решил вектор и добавлен суффикс 'X' в последний момент. Теперь исправлено. – Iftah

+0

Привет, я принял еще один ответ, но это решение также отлично работает и имеет несколько иной аффект :) Спасибо за помощь. – Henryz