2017-02-09 55 views
-1

旋轉的代碼是:如何在不使用旋轉命令的情況下在Pygame中旋轉我的曲面?

pygame.transform.rotate(surface, angle) 

但我不希望使用的代碼。我想寫一個自己旋轉曲面的代碼。我怎樣才能做到這一點?

+1

你的第一步是告訴我們爲什麼你不想使用該命令......否則,我們不知道你想要什麼,也不知道爲什麼你想要它! – Douglas

+1

你爲什麼要那樣做?這個問題不是很好... – XCode

+3

要自己旋轉曲面,最好的選擇是將其轉換爲[surfarray](http://www.pygame.org/docs/ref/surfarray.html)並應用變換矩陣(更具體地說是[旋轉矩陣](https://en.wikipedia.org/wiki/Rotation_matrix))。 Pygame不擅長手動操作像素,所以它很可能會很慢。使用'pygame.transform.rotate'是你的最佳選擇,但是如果主要關注的是你想學習的內容,那麼你可能需要研究線性代數和矩陣計算。目前的問題太廣泛了。 –

回答

-2
import pygame 

SIZE = 1000, 900 

pygame.init() 

screen = pygame.display.set_mode(SIZE) 

a=0 

done = False 

screen.fill((0, 0, 0)) 

other1 = pygame.image.load("image.jpg") 

screen.blit(other1, (0, 0)) 

while not done: 

    for event in pygame.event.get(): 

     if event.type == pygame.KEYDOWN: 

      if event.key == pygame.K_LEFT: 

       a=a+90 

       other2 = pygame.transform.rotate(other1, a) 

       screen.blit(other2, (0, 0)) 

      if event.key == pygame.K_RIGHT: 

       a=a-90 

       other2 = pygame.transform.rotate(other1, a) 

       screen.blit(other2, (0, 0)) 

    screen.fill((0,0,0)) 

    pygame.display.flip() 
+0

這個答案不會試圖回答這個問題。你剛纔複製了[你的問題]的代碼(http://stackoverflow.com/questions/42153719/how-can-i-rotate-an-image-in-pygame-with-out-current-commandwith-out -pygame-tr),這是這個問題的重複。 –

0

有解決這個問題很多不同的方式,但我的解讀是,它應該通過旋轉度,逆時針旋轉圖像,並根據需要調整圖像大小。我還包括一個crop功能,以消除過度的噪音。雖然,我的實現仍然存在問題,主要是它的aliased。要解決它,你可以看看this答案。

要旋轉圖像,首先需要將圖像轉換爲矩陣。這可以在pygame.surfarray.array3d的幫助下完成,但它需要你安裝numpy。然後我們需要一個rotation matrix和一個新的矩陣,我們將從我們的圖像複製所有像素。將位置矢量與旋轉矩陣相乘時,您將獲得一個新的位置矢量。因此,我們所做的只是遍歷圖像的x-y座標,將旋轉矩陣應用於每個座標,然後在新矩陣中的新座標處添加像素。

import numpy as np 
from math import sin, cos, radians 
import pygame 
pygame.init() 

SIZE = WIDTH, HEIGHT = 720, 480 
FPS = 30 
screen = pygame.display.set_mode(SIZE) 
clock = pygame.time.Clock() 


def crop(array, background=(0, 0, 0)): 
    rows, cols, _ = array.shape 
    left, right, top, bottom = 0, cols, 0, rows 

    for row in range(rows): 
     if not np.all(array[row] == background): 
      top = row 
      break 
    for row in range(rows - 1, top, -1): 
     if not np.all(array[row] == background): 
      bottom = row 
      break 

    np.transpose(array, axes=(1, 0, 2)) 

    for col in range(cols): 
     if not np.all(array[col] == background): 
      left = col 
      break 
    for col in range(cols - 1, left, -1): 
     if not np.all(array[col] == background): 
      right = col 
      break 

    np.transpose(array, axes=(1, 0, 2)) 

    return array[top:bottom+1, left:right+1] 


def rotate(surface, angle): 
    rect = surface.get_rect() 
    width, height = surface.get_size() 
    image_array = pygame.surfarray.array3d(surface) 

    angle = radians(angle) 

    # Rotation matrix: https://en.wikipedia.org/wiki/Rotation_matrix 
    rotation = np.array(
     ((cos(angle), -sin(angle)), 
     (sin(angle), cos(angle)) 
     ), dtype=np.float16 
    ) 

    # Rotates the corners of the image because the distance between 2 opposite corners will always be the furthest 
    # distance. This helps us calculate the new width and height of our new rotated image. 
    y_list, x_list = zip(*(
     (position @ rotation) for position in (rect.topleft, rect.topright, rect.bottomleft, rect.bottomright) 
    )) 
    min_x, min_y = min(x_list), min(y_list) 
    new_width = int(abs(min_x - max(x_list))) + 1 
    new_height = int(abs(min_y - max(y_list))) + 1 

    # Since we're rotating the image at the topleft corner and not in the center it'll be moved. By adding the offset 
    # we just move it back in place. 
    offset = -int(min_y), -int(min_x) 

    rotated_image_array = np.zeros(shape=(new_height, new_width, 3), dtype=np.uint8) 

    for row in range(height): # Not the newly calculated height, but the original image's height. 
     for col in range(width): 
      y, x = (row, col) @ rotation + offset 
      rotated_image_array[int(y), int(x)] = image_array[row, col] 

    rotated_image_array = crop(rotated_image_array) 

    return pygame.surfarray.make_surface(rotated_image_array) 


def main(): 
    running = True 
    original_image = pygame.Surface((200, 200)) 
    original_image.fill(pygame.Color('red')) 
    image = original_image 
    while running: 

     clock.tick(FPS) 

     for event in pygame.event.get(): 
      if event.type == pygame.QUIT: 
       running = False 
      elif event.type == pygame.KEYDOWN: 
       if event.key == pygame.K_ESCAPE: 
        running = False 
       elif event.key == pygame.K_1: 
        print('Reset image.') 
        image = original_image 
       elif event.key == pygame.K_2: 
        print('Starting rotating.') 
        time = pygame.time.get_ticks() 
        image = rotate(image, 20) 
        time = pygame.time.get_ticks() - time 
        print('Finished rotating in {:.4E} s.'.format(time/1000)) 

     screen.fill((255, 255, 255)) 
     screen.blit(image, image.get_rect(center=(WIDTH // 2, HEIGHT // 2))) 
     pygame.display.update() 


if __name__ == '__main__': 
    main() 
相關問題