Есть прямоугольник, чьи вершины заданы левой верхней точкой (x1, y1) и правой нижней (x2, y2). Необходимо произвести вращение прямоугольника вокруг произвольной точки (x0, y0) на угол α и найти координаты всех вершин после поворота.
Теория
Используем аффинные матрицу поворота и матрицу переноса. Формулы для нахождения координат при повороте следующие:
Точка вокруг которой хотим повернуть изображение имеет координаты O (x0, y0) . Чтобы получить значение x и y для формул выше, необходимо их нормализовать.
Смещение D(x,y) определяет, куда хотим поместить точку вращения после поворота. В подавляющем большинстве случаев оно равно точке вращения.
Окончательный вид формул:
Интерактив
На интерактиве ниже работают только эти формулы. «Произвольная» точка вращения зазывно мигает. Дескать, можно таскать. За вершины «не-повернутого» серого прямоугольника также можно таскать, меняя тем самым исходные координаты. При изменении координат происходит масштабирование с таким расчетом, чтобы «влез» процесс поворота. Делать на всю ширь возможных орбит смысла не увидел, т.к. они могут быть астрономически большими.
Переключатель «Математическая координатная сетка» показывает родную для математиков систему координат с центром координат посередине и осью Y, направленной вверх. Если режим выключен, демонстрируется координатная сетка, привычная для программистов — начало координат в левом верхнем углу и ось Y направлена вниз.
Переключатель «Анимация» включает плавное изменение угла с целью медитативного эффекта познания сущего.
Чтобы их увидеть включите режим математической сетки и сдвиньте точку вращения в положительный сектор, который находится в правом верхнем квадранте.
Немного кода
Delphi
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// Посчитать координаты точки повернутой на Angle радиан function CalcAnglePoint(const ACenter, APoint: TPointF; const Angle: Single): TPointF; var sn,cs: single; begin SinCos(Angle, sn, cs); Result.X := (APoint.X-ACenter.X) * cs - (APoint.Y-ACenter.Y) * sn + ACenter.X; Result.Y := (APoint.X-ACenter.X) * sn + (APoint.Y-ACenter.Y) * cs + ACenter.Y; end; |
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// расчет координат вершин по углу и центру вращения // angle - угол в радианах // center - точка, вокруг которой происходит вращение // points - массив с координатами вершин прямоугольника // vpoints - массив с повернутыми координатами вершин // массивы points и vpoints должны быть одной размерности ssin = Math.sin(angle); scos = Math.cos(angle); for (let i = 0; i < points.length; i++) { vpoints[i].x = center.x + (points[i].x - center.x) * scos - (points[i].y - center.y) * ssin; vpoints[i].y = center.y + (points[i].x - center.x) * ssin + (points[i].y - center.y) * scos; } |
Вращение прямоугольника вокруг произвольной точки и нахождение координат вершин производится таким незамысловатым кодом. Стоит отметить, что функции применимы к любому количеству вершин. Таким образом можно посчитать координаты любого многоугольника.
Друзья, спасибо за внимание!
Подписывайтесь на телегу.
Пишите комментарии.
Спрашивайте.
Что делать если при вращении фигура уменьшается?
Можно ли узнать подробности, какой-нибудь пример? От вращения фигура не уменьшается, тут должно быть дополнительно преобразование масштаба
спасибо, всё работает.