I suggest to use pygame.math.Vector2.rotate()
. The following works if the image is rotated around a pivot. See How do I rotate an image around its center using PyGame? and How to set the pivot point (center of rotation) for pygame.transform.rotate()? .
- Calculate the vector from the pivot to the point
- Rotate the vector with
pygame.math.Vector2.rotate()
- Add the pivot to the rotated vector
point = pygame.math.Vector2(turretx, turretY)
pivot = pygame.math.Vector2(self.x + 0.5*self.w, self.y + 0.5*self.h)
rotated_point = (point - pivot).rotate(-facingAngle) + pivot
t1x, t1y = rotated_point.x, rotated_point.y
Note that you need to rotate the vector by the negative angle. While pygame.transform.rotate
works clockwise, pygame.math.Vector2.rotate()
works counterclockwise.
In the following minimal example the pivot point is marked with the blue cross and the rotating point with the green cross. The rotated vector is the blue line between the blue cross and the green cross.

import pygame
pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
image_size = (160, 80)
point_on_image = (130, 40)
image = pygame.Surface(image_size, pygame.SRCALPHA)
pygame.draw.ellipse(image, "gray", (0, 0, *image_size))
pygame.draw.circle(image, "red", point_on_image, 10)
angle = 0
run = True
while run:
clock.tick(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window_center = window.get_rect().center
rotated_image = pygame.transform.rotate(image, angle)
px = window_center[0] - image_size[0]//2 + point_on_image[0]
py = window_center[1] - image_size[1]//2 + point_on_image[1]
point = pygame.math.Vector2(px, py)
pivot = pygame.math.Vector2(window_center)
rotated_point = (point - pivot).rotate(-angle) + pivot
window.fill("white")
window.blit(rotated_image, rotated_image.get_rect(center = window_center))
pygame.draw.line(window, "blue", (window_center[0]-15, window_center[1]), (window_center[0]+15, window_center[1]), 3)
pygame.draw.line(window, "blue", (window_center[0], window_center[1]-15), (window_center[0], window_center[1]+15), 3)
pygame.draw.line(window, "green", (rotated_point[0]-15, rotated_point[1]), (rotated_point[0]+15, rotated_point[1]), 3)
pygame.draw.line(window, "green", (rotated_point[0], rotated_point[1]-15), (rotated_point[0], rotated_point[1]+15), 3)
pygame.draw.line(window, "blue", window_center, rotated_point, 3)
pygame.display.flip()
angle +=1
pygame.quit()
exit()
If you do not rotate the image around its center, but only keep the position at the top left, you must:
- Calculate the vector from the center of the original image to the point
- Rotate the vector with
pygame.math.Vector2.rotate()
- Add the center of the rotated image to the rotated vector
point = pygame.math.Vector2(turretx, turretY)
pivot = pygame.math.Vector2(self.x + 0.5*self.w, self.y + 0.5*self.h)
rotatedFrigate = pygame.transform.rotate(gui.frigate[0], facingAngle)
new_pivot = pygame.math.Vector2(
self.x + 0.5 * rotatedFrigate.get_width(),
self.y + 0.5 * rotatedFrigate.get_height())
rotated_point = (point - pivot).rotate(-facingAngle) + new_pivot
t1x, t1y = rotated_point.x, rotated_point.y
Minimal example:

import pygame
pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
image_size = (160, 80)
point_on_image = (130, 40)
image = pygame.Surface(image_size, pygame.SRCALPHA)
pygame.draw.ellipse(image, "gray", (0, 0, *image_size))
pygame.draw.circle(image, "red", point_on_image, 10)
angle = 0
run = True
while run:
clock.tick(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window_center = window.get_rect().center
image_rect = image.get_rect(center = window_center)
rotated_image = pygame.transform.rotate(image, angle)
px = window_center[0] - image_size[0]//2 + point_on_image[0]
py = window_center[1] - image_size[1]//2 + point_on_image[1]
point = pygame.math.Vector2(px, py)
pivot = pygame.math.Vector2(window_center)
rotated_image_rect = rotated_image.get_rect(topleft = image_rect.topleft)
rotated_image_center = rotated_image_rect.center
rotated_point = (point - pivot).rotate(-angle) + rotated_image_center
window.fill("white")
window.blit(rotated_image, rotated_image_rect)
pygame.draw.rect(window, "black", rotated_image_rect, 3)
pygame.draw.line(window, "blue", (rotated_image_center[0]-15, rotated_image_center[1]), (rotated_image_center[0]+15, rotated_image_center[1]), 3)
pygame.draw.line(window, "blue", (rotated_image_center[0], rotated_image_center[1]-15), (rotated_image_center[0], rotated_image_center[1]+15), 3)
pygame.draw.line(window, "green", (rotated_point[0]-15, rotated_point[1]), (rotated_point[0]+15, rotated_point[1]), 3)
pygame.draw.line(window, "green", (rotated_point[0], rotated_point[1]-15), (rotated_point[0], rotated_point[1]+15), 3)
pygame.draw.line(window, "blue", rotated_image_center, rotated_point, 3)
pygame.display.flip()
angle +=1
pygame.quit()
exit()