I have a small problem that could have a simple solution, but unfortunately I'm not very good at math.
I have three images that need to be stacked on top of each other and their heights add up to more than the screen height.
So to fix, I did a simple proportion and changed the height of the three images, like this (it's hypothetical, not the actual code):
new_img1.height = img1.height * screen.height // (img1.height img2.height img3.height)
The problem I'm having is doing the same thing, but with the width, considering all three images have the same width.
What I want is that the three images always have the same width as originally, but resized with the new height (so that the three images are proportionally smaller in both dimensions)
I've made several attempts, but my mathematical limits don't help me much XD
How should I fix? Ah, I'm using Python 3.9 with Pygame (although for the latter I don't think it needed to know)
CodePudding user response:
If you want to keep the aspect ratio, you must scale the width and height of the image with the same scaling factor:
scale_factor = screen.height // (img1.height img2.height img3.height)
new_img1.width = img1.width * scale_factor
new_img1.height = img1.height * scale_factor
new_img2.width = img2.width * scale_factor
new_img2.height = img2.height * scale_factor
new_img3.width = img3.width * scale_factor
new_img3.height = img3.height * scale_factor
If you want all images to have the same width, you must first calculate the scale factor for each image to scale the width of the images. Then you can calculate the scale factor for the height:
max_width = max(img1.width, img2.width, img3.width)
scale_factor1 = max_width / img1.width
scale_factor2 = max_width / img2.width
scale_factor3 = max_width / img3.width
height_scale = screen.height / (img1.height * scale_factor1 img2.height * scale_factor2 img3.height * scale_factor3)
scale_factor1 *= height_scale
scale_factor2 *= height_scale
scale_factor3 *= height_scale
Minimal example to demonstrate the algorithm:
import pygame, random
pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
update_rects = True
run = True
while run:
clock.tick(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
update_rects = True
if update_rects:
rect1 = pygame.Rect(0, 0, random.randrange(50, 100), random.randrange(50, 100))
rect2 = pygame.Rect(0, 0, random.randrange(50, 100), random.randrange(50, 100))
rect3 = pygame.Rect(0, 0, random.randrange(50, 100), random.randrange(50, 100))
update_rects = False
max_width = max(rect1.width, rect2.width, rect2.width)
scale_factor1 = max_width / rect1.width
scale_factor2 = max_width / rect2.width
scale_factor3 = max_width / rect3.width
height_scale = window.get_height() / (rect1.height * scale_factor1 rect2.height * scale_factor2 rect3.height * scale_factor3)
scale_factor1 *= height_scale
scale_factor2 *= height_scale
scale_factor3 *= height_scale
rect1.width *= scale_factor1
rect1.height *= scale_factor1
rect2.width *= scale_factor2
rect2.height *= scale_factor2
rect3.width *= scale_factor3
rect3.height *= scale_factor3
rect2.top = rect1.bottom
rect3.top = rect2.bottom
window.fill(0)
pygame.draw.rect(window, "red", rect1)
pygame.draw.rect(window, "blue", rect2)
pygame.draw.rect(window, "yellow", rect3)
pygame.display.flip()
pygame.quit()
exit()