Привет, если ты читаешь эту статью, значит ты хочешь узнать ответ на вопрос «как работает вращение объекта в 2D ?»
Ты скорее всего знаешь что во всех современных движках, таких как Unity вращение осуществляется с помощью функции, но нам интересно, как можно написать алгоритм
вращения своими руками.
Если проще то наш алгоритм работает так.
Мы представляем окружность, где:
Итак, начнем.
Давайте взглянем на рисунок ниже:

Давайте попробуем применить формулы:
Не сложно догадаться что делает этот код, а именно вращает наш кружок по оси, но почему лишь один раз?
Давайте вспомним уроки геометрии в седьмом классе: градусная мера угла не может превышает 360 градусов.
А если попробуем обнулять угол вращения, когда тот будет больше 360 градусов, давайте посмотрим что из этого выйдет:
Этот код позволяет вращать кружок по оси бесконечно.
Однако у этой формулы есть один недостаток: можно вращать объекты только на 1 оборот. Это значит что нам нужна другая формула.
Давайте улучшим нашу формулу:
Теперь у нас есть формула которая позволяет бесконечно вращать точку по окружности: $$display$$xPos = (lineLong * cos(a +arccos((xPos — startPosX): lineLong))) + startPosX$$display$$
Давайте напишем код, который будет вращать наш объект по нажатию на клавишу.
Примерно таком образом решается эта задача.
Надеюсь, ты смог извлечь полезную информацию из моего поста, желаю удачно применить полученные знания на практике
Ты скорее всего знаешь что во всех современных движках, таких как Unity вращение осуществляется с помощью функции, но нам интересно, как можно написать алгоритм
вращения своими руками.
Если проще то наш алгоритм работает так.
Мы представляем окружность, где:
- Центр это точка, вокруг которой мы вращаем объект.
- Радиус — расстояние от центра до вращаемого объекта.
Итак, начнем.
Давайте взглянем на рисунок ниже:

Дано: длинна радиуса, координаты точки вращения, угол АОВ, АВ перпендикулярен оси ОХ.
Задача: Задать вращение точки А на 360 градусов с помощью формулы.
Рассмотрим: треугольник ОАВ:
угол ОВА — прямой => треугольник ОАВ — прямоугольный треугольник;
тогда:
гипотенуза = радиусу окружности с центром в точке О
угол поворота = от 1 до 360 градусов
тогда чтобы найти катеты ОВ и АВ нужно:
АВ = радиус * cos(угла поворота),
ОВ = $inline$радиус * sin(угла поворота)$inline$
Теперь когда мы знаем размеры катетов
мы составим формулу:
для координаты по x:$inline$позиция по x = радиус * cos(угла поворота) + начальная позиция по x$inline$,
и для координаты по y: $inline$позиция по y = радиус * sin(угла поворота) + начальная позиция по y$inline$
Давайте попробуем применить формулы:
import pygame, math
#colors
black = (0, 0, 0)
size = (500, 500)
screen = pygame.display.set_mode(size)
a = b = 200
clock = pygame.time.Clock()
FPS = 60
for i in range(1, 361, 3):
clock.tick(FPS)
angle = i * 3.14 / 180
a = 100 * math.cos(angle) + 300
b = 100 * math.sin(angle) + 300
screen.fill(black)
pygame.draw.circle(screen, (122, 0, 0), (int (a), int (b)), 6)
pygame.display.update()
Не сложно догадаться что делает этот код, а именно вращает наш кружок по оси, но почему лишь один раз?
Давайте вспомним уроки геометрии в седьмом классе: градусная мера угла не может превышает 360 градусов.
А если попробуем обнулять угол вращения, когда тот будет больше 360 градусов, давайте посмотрим что из этого выйдет:
import pygame, math
#colors
red = (122 , 0, 0)
green = (0, 122, 0)
black = (0, 0, 0)
size = (500, 500)
screen = pygame.display.set_mode(size)
a = b = 200
i = 0
clock = pygame.time.Clock()
FPS = 60
while True:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit()
screen.fill(black)
pygame.draw.circle(screen, red, (int (a), int (b)), 6)
if i <= 360: # здесь мы ставим ограничения, что-бы питон не выдал нам ошибку.
angle = i * (3.14 / 180) # перевод из градусов в радианы
a = 100 * math.cos(angle) + 300
b = 100 * math.sin(angle) + 300
i += 3 # здесь мы увеличиваем угол перемещения.
else:
i = 0 #обнуляем i потому - что, углов > 360 градусов нет, а кружок прошел свой путь
Этот код позволяет вращать кружок по оси бесконечно.
Однако у этой формулы есть один недостаток: можно вращать объекты только на 1 оборот. Это значит что нам нужна другая формула.
Давайте улучшим нашу формулу:

Дано:
треугольник ОАВ — прямоугольный
катет 1 = x1 — начальная координата X
катет 2 = y1 — начальная координата y
Задача:
улучшить формулу так, что-бы можно было вращать точку А на неизвестный угол.
Решение:
Из предыдущей задачи мы знаем что:
$inline$$inline$xPos = (lineLong * cos(a)) + StartPosX$inline$$inline$. => $inline$cos(a) = xPos — startPosX: (lineLong )$inline$
И теперь мы можем вывести формулу по нахождению угла a
$inline$yPos = (lineLong * sin(a)) + StartPosY$inline$ => $$display$$a = arccos((xPos — startPosX): lineLong)$$display$$.
А сейчас обновим нашу формулу и получим: $$display$$xPos = (lineLong * cos(a +b)) + startPosX$$display$$
Теперь у нас есть формула которая позволяет бесконечно вращать точку по окружности: $$display$$xPos = (lineLong * cos(a +arccos((xPos — startPosX): lineLong))) + startPosX$$display$$
Давайте напишем код, который будет вращать наш объект по нажатию на клавишу.
import pygame, math
#colors
black = (0, 0, 0)
green = (0, 122, 0)
size = (600, 600)
screen = pygame.display.set_mode(size)
a = b = 500
i = 0
clock = pygame.time.Clock()
FPS = 60
while True:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit()
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT]:
angle = i * 3.14 / 180
l = math.acos((a - 400) / math.sqrt(500 ** 2 - 400 **2))
int(l)
a = (100 * math.cos(angle + l)) + 400
b = (100 * math.sin(angle + l)) + 400
i -= 3
elif keys[pygame.K_LEFT]:
angle = i * 3.14 / 180
l = math.acos((a - 400) / math.sqrt(500 ** 2 - 400 **2))
int(l)
a = (100 * math.cos(angle + l)) + 400 # 400 - начальная точка по х и по у
b = (100 * math.sin(angle + l)) + 400
i += 3
screen.fill(black)
pygame.draw.circle(screen, green, (int (a), int (b)), 6)
pygame.display.update()
Примерно таком образом решается эта задача.
Надеюсь, ты смог извлечь полезную информацию из моего поста, желаю удачно применить полученные знания на практике