pygame-ce icon indicating copy to clipboard operation
pygame-ce copied to clipboard

pygame.transform.rotate_center

Open ScriptLineStudios opened this issue 9 months ago • 7 comments

pygame.transform.rotate_center(surface: Surface, angle: float) -> Surface

Rotating an image around it's center is fairly common, it could be nice to have it as part of the transform API. If we can come to an agreement on whether this should be added or not, I've got a draft PR ready to go.

ScriptLineStudios avatar Mar 10 '25 09:03 ScriptLineStudios

Can you show me a result surface rotating normally and a result surface rotating like this? in my mind they would produce the same result, so I'm having a hard time justifying this in my mind

damusss avatar Mar 10 '25 12:03 damusss

@damusss

Image

ScriptLineStudios avatar Mar 10 '25 20:03 ScriptLineStudios

oh wow, damn, wow, I support this, sure

damusss avatar Mar 10 '25 21:03 damusss

Mark the corners of your sprite and you'll see why it behaves like this. @ScriptLineStudios I have no clue how would you like it to work. Cut out the parts that are outside the original rect? Why would it be useful? This works in your case only because the image is closely shaped to a circle...

gresm avatar Mar 10 '25 21:03 gresm

@gresm you have a point, and additionally, isn't the sprite on the left being slightly cut off? like when the horizontal parts need to start rotating, or is it just me? when I first saw it I was a bit mesmerized, but I think that to achieve something close to the image of the left without cutting out anything one can use the Mask class and find the bounding rect and then cut, or cut just like you said.

damusss avatar Mar 10 '25 21:03 damusss

Technically pygame.transform.rotate() and similar already rotate around the center. I think rotate_center would be a bit confusing.

The suggested function would be more like a "cropped" version of pygame.transform.rotate() with the behavior that it always preserves size, which works best on square surfaces. Note that for more rectangular surfaces, much would be cut out for certain angles. Also note that corner padding would be necessary for most angles.

pygame.transform.rotate_cropped(surface: Surface, angle: float) -> Surface

aatle avatar Mar 10 '25 23:03 aatle

If we are going to expand on rotate I would just make a generic rotate_on_pivot function where the pivot point can be changed as needed.

This is what I use, its a bit different in that it returns a rect as well but that rect can be used to position the image correctly after rotation around any pivot / origin point. Caching can be optional.

rot_cache = {}
def rotate_on_pivot(image: pygame.Surface, angle: float, pivot: Vector2, origin: Vector2) -> tuple[pygame.Surface, pygame.Rect]:
    
    lookup = (image, angle)
    
    if lookup in rot_cache:
        surf = rot_cache[lookup]
    else:
        surf = pygame.transform.rotate(image, angle)
        rot_cache[lookup] = surf
        
    return surf, surf.get_rect(center = ((origin - pivot).rotate(-angle) + pivot))

bigwhoopgames avatar Mar 12 '25 03:03 bigwhoopgames