Страницы

Поиск по вопросам

вторник, 25 февраля 2020 г.

Линейное движение точки под углом: отскок

#анимация #алгоритм #геометрия


Приветствую.
В общих чертах, пишу алгоритм перемещения точки в пределах прямоугольника, скажем
600 x 400. Точка имеет такие свойства:

текущие координаты X и Y, при чем, X = [0,600]; Y = [0,400] (просто перемещаю div
по relative-контейнеру)
кинетический заряд A (длина шага за 1 такт — гипотенуза)
угол Angle (град.)

Сначала долго ломал голову насчет самого передвижения точки в направлении, указанном
углом Angle. Когда обнаружил решение, стало стыдно. Вот оно:
X = X + A * cos(Angle * PI / 180);
Y = Y + A * sin(Angle * PI / 180);

С этим все нормально:

если Angle = 0, то точка движется вправо по OX,
если Angle = 180, то влево,
если Angle = 90, то вниз по OY (!),
если 45 — то вправо-вниз...

Но уже битый час не могу понять, какие ставить условия и как разворачивать угол при
столкновении со «стеной» прямоугольника, которым описана площадь, за которую точка
не должна вылезти.
В каждой итерации (такт) происходит смещение точки по приведенным выше формулам и
делается тест на столкновение. Извиняюсь за толстую просьбу, но я прошу дополнить (поправить?)
эту секцию кода:
if (x <= 0)
    { Angle = ... }
else if (x >= 600)
    { Angle = ... }

if (y <= 0)
    { Angle = ... }
else if (y >= 400)
    { Angle = ... }

И еще у меня может быть и само движение неправильно описано, тоже поправьте пожалуйста,
если так (у меня такое впечатление, что по-правильному, с увеличением угла Angle траектория
точки должна заворачиваться против, а не по часовой — как у меня).    


Ответы

Ответ 1



исправил я функцию step, обратите внимания на коментарии this.step = function() { this.x = this.x + this.a * Math.cos(this.angle * Math.PI / 180); this.y = this.y + this.a * Math.sin(this.angle * Math.PI / 180); if (this.x <= 0) { // this.angle = 180 - this.angle; if (this.angle < 0) this.angle += 360; // что бы угол был положительным } else if (this.x >= 600) { // 0 -> 180 10 -> 170 this.angle = 180 - this.angle; if (this.angle < 0) this.angle += 360; } if (this.y <= 0) { // 270 -> 90 269 -> 91 this.angle = 360 - this.angle; } else if (this.y >= 400) { // 90 -> 279 180 - 180 this.angle = 360 - this.angle; } return this; }; или даже ещё короче this.step = function() { this.x = this.x + this.a * Math.cos(this.angle * Math.PI / 180); this.y = this.y + this.a * Math.sin(this.angle * Math.PI / 180); if (this.x <= 0 | this.x >= 600) { // this.angle = 180 - this.angle; if (this.angle < 0) this.angle += 360; } if (this.y <= 0 | this.y >= 400) { // 270 -> 90 269 -> 91 this.angle = 360 - this.angle; } return this; };

Комментариев нет:

Отправить комментарий