Найти в Дзене

ЮНЫМ ПРОГРАММИСТАМ: Как повернуть точку вокруг точки?

Как-то напал на что-то вроде форума, где обсуждалась тема поворотов в пространстве с помощью разных методов. Решил вот написать пока как повернуть точку с координатами (x; y) вокруг точки с координатами (x0; y0) на угол альфа против часовой стрелки. Пока на плоскости. Да, впрочем, такой же принцип будет и в пространстве. Или, как сейчас круто говорить: в 3D. Короче, как повернуть точку вокруг точки... Вот текст программы на языке Python: # подготовка графики from tkinter import * w=Tk() aokn=w.winfo_screenwidth(); bokn=w.winfo_screenheight() if aokn<1920: bokn=int(aokn*1080/1920) a=int(aokn); b=int(bokn) p = aokn / 1920; v = bokn / 1080 aokn=aokn//2-a//2; bokn=bokn//2-b//2 w.geometry('{}x{}+{}+{}'.format(a,b, aokn, bokn)) c=Canvas(width=a, height=b, bg='black') c.pack() import math # загрузка математики # рисование сетки и осей координат for i in range(31): c.create_line(510*p, 30*v*i+50*v, 1410*p, 30*v*i+50*v, fill='gray') c.create_line(510*p+30*p*i, 50*v, 510*p+30*p*i,

Как-то напал на что-то вроде форума, где обсуждалась тема поворотов в пространстве с помощью разных методов. Решил вот написать пока как повернуть точку с координатами (x; y) вокруг точки с координатами (x0; y0) на угол альфа против часовой стрелки. Пока на плоскости. Да, впрочем, такой же принцип будет и в пространстве. Или, как сейчас круто говорить: в 3D. Короче, как повернуть точку вокруг точки...

Вот текст программы на языке Python:

# подготовка графики

from tkinter import *

w=Tk()

aokn=w.winfo_screenwidth(); bokn=w.winfo_screenheight()

if aokn<1920: bokn=int(aokn*1080/1920)

a=int(aokn); b=int(bokn)

p = aokn / 1920; v = bokn / 1080

aokn=aokn//2-a//2; bokn=bokn//2-b//2

w.geometry('{}x{}+{}+{}'.format(a,b, aokn, bokn))

c=Canvas(width=a, height=b, bg='black')

c.pack()

import math # загрузка математики

# рисование сетки и осей координат

for i in range(31):

c.create_line(510*p, 30*v*i+50*v, 1410*p, 30*v*i+50*v, fill='gray')

c.create_line(510*p+30*p*i, 50*v, 510*p+30*p*i, 950*v, fill='gray')

c.create_line(510*p, 500*v, 1410*p, 500*v, fill='white')

c.create_line(960*p, 50*v, 960*p, 950*v, fill='white')

# математические координаты точки, вокруг которой поворачиваем

x0 = 3; y0 = 2

# математические координаты точки, которую поворачиваем

x = 6; y = 2

# угол поворота в градусах

a = 45

# перевод угла в радианы

a = a * math.pi / 180

# формулы поворота

xn = (x-x0) * math.cos(a) - (y-y0) * math.sin(a) + x0

yn = (x-x0) * math.sin(a) + (y-y0) * math.cos(a) + y0

# перевод математических координат в экранные

x0e = 960 * p + 30 * x0 * p # центр поворота

y0e = 500 * v - 30 * y0 * v # центр поворота

xe = 960 * p + 30 * x * p # исходная точка

ye = 500 * v - 30 * y * v # исходная точка

xne = 960 * p + 30 * xn * p # повёрнутая точка

yne = 500 * v - 30 * yn * v # повёрнутая точка

# РИСОВАНИЕ

r = 10 # радиус кружочка

# линия от центра поворота к исходной точке

c.create_line(x0e, y0e,xe,ye, fill='white', width=4)

# линия от центра поворота к повёрнутой точке

c.create_line(x0e, y0e,xne,yne, fill='white', width=4)

# центр поворота

c. create_oval(x0e - r, y0e - r, x0e + r, y0e + r, fill ='yellow', outline='white')

# исходная точка

c. create_oval(xe - r, ye - r, xe + r, ye + r, fill ='red', outline='white')

# повёрнутая точка

c. create_oval(xne - r, yne - r, xne + r, yne + r, fill ='magenta', outline='white')

Этот текст можно скопировать и вставить в редактор Питона. Так как Питон любит делать дурацкие отступы, то в блоке "рисование сетки и осей координат" после fora две строки должны быть с отступами. Короче, вот фотки, они показывают, как должен выглядеть текст проги в редакторе Питона:

-2
-3

На блоке "подготовка графики" останавливаться не хочу. Просто примите его как есть. Менять его непринципиально. Обратите лишь внимание на переменные p и v - это масштабные коэффициенты для разного разрешения мониторов. Лучше их не трогать.

Блок "рисование сетки и осей координат" нужен только для наглядности. Его можно убрать. Но надо помнить, что центр координат (0; 0) находится на мониторе 1920х1080 в точке (960; 500), а размер клеточек сетки 30х30 мониторных точек.

Самое интересное, из-за чего сыр-бор, начинается с блока "математические координаты точки, вокруг которой поворачиваем". Это переменные (x0; y0). Вы можете дать им другие значения, разумные, в пределах от -10 до 10. Это точка, вокруг которой поворачиваем.

Далее идут координаты точки, которую поворачиваем: (x; y). Вы можете дать им свои значение, разумные, недалеко от центра вращения, чтобы исходная точка и потом повёрнутая была в пределах монитора.

Затем угол поворота. Это переменная а. Может быть не стоило обозначать её а, так как выше уже была переменная а, ну да ладно, сойдёт и так, прога всё равно работает. Угол а Вы задаёте в градусах. Здесь а = 45 градусов. Вы можете поменять его на 120, 270, 193 и т.д. В следующей строке а умножается на число пи и делится на 180, таким образом градусы переводим в радианы, так как синусы и косинусы считают в них.

И, наконец, совсем секретные формулы поворотов. Менять в них ничего не надо. Такими их мама-математика родила. Формулы поворотов из старых координат (x; y) делают новые, повёрнутые, координаты (xn; yn). Состоят эти формулы поворотов сначала из формул параллельного переноса в начало координат, потом поворота вокруг него и уже потом возвращения параллельным переносом обратно.

Далее. До сих пор вычисления проводились с математическими, то есть с истинными координатами. Но на мониторе свои экранные координаты. Формулами параллельного переноса и гомотетии математические координаты надо перевести в экранные. В формулах перевода опять менять ничего не надо, чтобы не напутать.

Как только экранные координаты вычислены, по ним можно рисовать. Я изобразил центр поворота жёлтым кружочком, исходную точку - красным, повёрнутую точку - экзотическим цветом magenta. Соединил центр вращения с точками линиями. Радиус кружочков сидит в переменной r. Цвета, конечно, можно менять, линии убрать. Главное - это принцип - формулы поворота. Далее можно выдумать мультик, где кружочек движется непрерывно вокруг центра вращения. И так далее. Если интересно как это сделать - пишите, подскажу.

При запуске эта программа выдаёт картинку:

-4

Успехов Вам в программировании!