Страницы

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

четверг, 2 мая 2019 г.

Как держать два объекта на постоянном расстоянии друг от друга?

Здравствуйте! Такая задача: есть две точки, они должны держаться на постоянном расстоянии друг от друга. Если начинаешь двигать за одну точку, то другая идет следом за ней, как бы два конца одной палки.


Как это можно реализовать? В одной книге про анимации была написана следующая реализация:
function springTo(pointA, pointB) { var dx = pointB.x - pointA.x, dy = pointB.y - pointA.y, angle = Math.atan2(dy, dx), targetX = pointB.x - Math.cos(angle) * 100, targetY = pointB.y - Math.sin(angle) * 100;
pointA.vx += (targetX - pointA.x) * pointA.spring; pointA.vy += (targetY - pointA.y) * pointA.spring; pointA.vx *= pointA.friction; pointA.vy *= pointA.friction; pointA.x += pointA.vx; pointA.y += pointA.vy; }
Код написан на JS. Что делает этот код: в функцию передаются два значения (точка А и точка Б). В той части, где происходит инициализация переменных происходит подсчет конечного положения точки А, то есть того положения куда нужно сдвинуть точку, чтобы расстояние между точками было равным 100. Собственно потом мы точку А двигаем в нужном направлении. Чем плох этот способ для меня: точки двигаются плавно. Мне же нужно чтобы они двигались ровно, как палка.
Вот пример https://jsfiddle.net/0b1whd87/1/ , чтобы было понятнее.


Ответ

Пример решения: https://jsfiddle.net/gambala/urzmyv5x/
Алгоритм:
Головная точка (за которую цепляем) мгновенно перемещается туда, где курсор; Хвостовая точка (другая из двух) встает так, чтобы расстояние между ей и головной не изменилось (было 50px, осталось 50px, без пружинивания).
Для этого хвостовая точка:
Поворачивается туда, куда перемещается головная точка; Делает столько шагов вперед (или назад), чтобы в итоге расстояние от нее до головной точки было таким же, как и всегда.
Это делает функция updateTailPoint
function updateTailPoint(tailPoint, handlePoint) { var dx = handlePoint.x - tailPoint.x, dy = handlePoint.y - tailPoint.y, angle = Math.atan2(dy, dx), distance = Math.sqrt(dx*dx + dy*dy); tailPoint.x += (distance - 50) * Math.cos(angle); tailPoint.y += (distance - 50) * Math.sin(angle); }
Где 50 - это "эталонное" расстояние между точками, которое хвостовая точка беспрекословно соблюдает.

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

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