Pygame: Как мне повернуть изображение и повернуть его, чтобы соединить две точки на экране? - PullRequest
1 голос
/ 26 сентября 2019

Вот тестовая программа.Я начал с двух случайных точек и линии, соединяющей их.Теперь я хочу взять заданное изображение (с размерами x, y 79 x 1080) и переместить его поверх направляющей линии.Я понимаю, что arctan даст мне угол между точками на декартовой сетке, но поскольку у - назад экрана (х, у), я должен инвертировать некоторые значения.Я запутался в шаге отрицания.

Если вы запустите это несколько раз, вы увидите, что изображение всегда параллельно линии, а иногда сверху, но не последовательно.

import math
import pygame
import random
pygame.init()
screen = pygame.display.set_mode((600,600))

#target = (126, 270)
#start = (234, 54)
target = (random.randrange(600), random.randrange(600))
start = (random.randrange(600), random.randrange(600))
BLACK = (0,0,0)
BLUE = (0,0,128)
GREEN = (0,128,0)

pygame.draw.circle(screen, GREEN, start, 15)
pygame.draw.circle(screen, BLUE, target, 15)
pygame.draw.line(screen, BLUE, start, target, 5)                        
route = pygame.Surface((79,1080))
route.set_colorkey(BLACK)
BMP = pygame.image.load('art/trade_route00.png').convert()
(bx, by, bwidth, bheight) = route.get_rect()
route.blit(BMP, (0,0), area=route.get_rect())
# get distance within screen in pixels
dist = math.sqrt((start[0] - target[0])**2 + (start[1] - target[1])**2)
# scale to fit: use distance between points, and make width extra skinny.
route = pygame.transform.scale(route, (int(bwidth * dist/bwidth * 0.05), int( bheight * dist/bheight)))
# and rotate... (invert, as negative is for clockwise)
angle = math.degrees(math.atan2(-1*(target[1]-start[1]), target[0]-start[0]))
route = pygame.transform.rotate(route, angle + 90 )
position = route.get_rect()
HERE = (abs(target[0] - position[2]), target[1]) # - position[3]/2)
print(HERE)
screen.blit(route, HERE)
pygame.display.update()
print(start, target, dist, angle, position)

enter image description here

1 Ответ

2 голосов
/ 26 сентября 2019

Основная проблема

Ошибка не связана с обратными координатами y (0 сверху, максимум снизу) при вращении, как вам кажется.Эта часть верна.Ошибка здесь:

HERE = (abs(target[0] - position[2]), target[1]) # - position[3]/2)

HERE должны быть координатами верхнего левого угла прямоугольника, на котором написаны ваши зеленые и синие точки, соединенные синей линией.В этих координатах вам нужно поместить Поверхность route после изменения масштаба.

Вы можете получить эту вершину, выполнив:

HERE = (min(start[0], target[0]), min(start[1], target[1])) 

Это должно решить проблему, и ваши цветные точки должнылежит на синей линии.

Примечание:

Еще одна вещь, которую вы, возможно, захотите исправить, это параметр масштабирования route:

route = pygame.transform.scale(route, (int(bwidth * dist/bwidth * 0.05), int( bheight * dist/bheight)))

Если мое предположениеправильно, и вы хотите сохранить исходное соотношение высоты и ширины в измененном масштабе route (поскольку ваше исходное изображение не является квадратом) это должно быть:

route = pygame.transform.scale(route, (int(dist* bwidth/bheight), int(dist)))

при условии, что вы хотите высоту (больший размерв оригинале) масштабируется до dist.Поэтому вам может не понадобиться 0.05, или вы можете использовать другой параметр сжатия (вероятно, 0,05 уменьшит его слишком сильно).

...