Три метода перемещения объекта на плоскости (15.10.2012)
Перенеся свои опыты по разработке двигательных поведенческих примитивов бегающих квадратиков на canvas, я наконец, чувствую, насколько просто и удобно, вкупе с объектным подходом, здесь все делать.
Первичное действие в анимации - движение предмета по прямой к установленной точке и я рассмотрю три способа это реализовать.
Первый способ я бы назвал "шашечками" - это передвижение по восьми возможным направлениям, где дистанция до цели определяется длиной наибольшей проекции на одну из осей координат. Способ предельно прост и каждый шаг четко укладывается в единицы системы координат, однако, не очень естественно выглядит предмет, нарезающий крутые углы по пути к цели.
Функции писались, как внутренние модификаторы объекта, поэтому this - это движущийся объект, а target - координаты цели. Переменная speed просто хранит количество единиц измерения на один шаг.

      if (this.x<target.x) this.x+=this.speed;
      if (this.x>target.x) this.x-=this.speed;
      if (this.y<target.y) this.y+=this.speed;
      if (this.y>target.y) this.y-=this.speed;

Следующий способ - тригонометрическое уравнение прямой. Путевая линия, конечно, строится, однако, функциональная зависимость вертикальной координаты от горизонтальной делает движение неравномерным в различных участках координатной плоскости и при часто выпадающих обстоятельствах, объект никогда не совместится с целевой точкой.

      var k = (target.y - this.y)/(target.x - this.x);
      var b = (target.x*this.y - this.x*target.y)/(target.x - this.x);
      if (this.x<target.x) this.x+=this.speed;
      else this.x-=this.speed;
      this.y = k*this.x+b;

Третий способ - движение по диагонали воображаемого прямоугольника, соединяющей объект и точку. Диагональ - или гипотенуза прямоугольного треугольника определяется по всем известной формуле. Далее представим на данной линии меньший прямоугольник, с диагональю, равной желаемой длине шага. По теореме подобия треугольников определим величины координат x и y.

      var distance = Math.round(Math.sqrt(Math.pow(Math.abs(this.x-target.x),2) + Math.pow(Math.abs(this.y-target.y),2)));
      this.x+=((target.x-this.x)*this.speed)/distance;
      this.y+=((target.y-this.y)*this.speed)/distance;

На данный момент я остановился на последнем варианте, как наиболее "прямом" и логичном. Примеры применения этих способов представлены ниже.

JavaScript, Canvas
comments powered by Disqus
JavaScript (13)
PHP (11)
Brainfuck (8)
adm (8)
Joomla (4)
Canvas (3)
answers (2)
API (2)
CMS (2)
Modx (2)
jQuery (1)
Ajax (1)
SQL (1)
Shell (1)
batch (1)
10-6