2022-01-24

Rotating and scaling an image around a pivot, while scaling width and height separately in Pygame

I have a set of keyframes in a list that look like this:

   [{
        "duration" : 20,
        "position" : [0,0],
        "scale" : [1, 1],
        "angle" : 0,
        "rgba" : [255,255,255,255]
    },
    {
        "duration" : 5,
        "position" : [0,0],
        "scale" : [1, 1.5],
        "angle" : 50,
        "rgba" : [255,255,255,255]
    }]

The idea is being able to do the corresponding transformations every frame. Notice that scale is separated between width and height.
The problem comes form trying to scale width and height independently, while still rotating around a pivot.

I tried modifying some code from: (How to rotate an image around its center while its scale is getting larger(in Pygame))

def blitRotate(surf, image, pos, originPos, angle, zoom):

    # calcaulate the axis aligned bounding box of the rotated image
    w, h       = image.get_size()
    box        = [pygame.math.Vector2(p) for p in [(0, 0), (w, 0), (w, -h), (0, -h)]]
    box_rotate = [p.rotate(angle) for p in box]
    min_box    = (min(box_rotate, key=lambda p: p[0])[0], min(box_rotate, key=lambda p: p[1])[1])
    max_box    = (max(box_rotate, key=lambda p: p[0])[0], max(box_rotate, key=lambda p: p[1])[1])

    # calculate the translation of the pivot 
    pivot        = pygame.math.Vector2(originPos[0], -originPos[1])
    pivot_rotate = pivot.rotate(angle)
    pivot_move   = pivot_rotate - pivot

    # calculate the upper left origin of the rotated image
    move   = (-originPos[0] + min_box[0] - pivot_move[0], -originPos[1] - max_box[1] + pivot_move[1])
origin = (pos[0] + zoom * move[0], pos[1] + zoom * move[1])

# get a rotated image
rotozoom_image = pygame.transform.rotozoom(image, angle, zoom)

# rotate and blit the image
surf.blit(rotozoom_image, origin)

# draw rectangle around the image
pygame.draw.rect (surf, (255, 0, 0), (*origin, *rotozoom_image.get_size()),2)

but i'm struggling trying to think of the math necessary to make it work, i've tried separating zoom into a dupe, and then instead of doing rotozoom , scaling first with transform.scale and then transform.rotate afterwards but that didn't work either.

To better illustrate what i mean, it would be something like this:
rotating around pivot while changing width and height

It changes it's width and height but the pivot stays the same



from Recent Questions - Stack Overflow https://ift.tt/3GTXYef
https://ift.tt/3AnVKBn

No comments:

Post a Comment