[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [pygame] Making a clock rotate



Hi dialtone:

I'm not exactly sure what you're trying to do with these trig functions, but I'm going to guess you're trying to keep the object's center at the original center even though the rotated rect grows as it rotates away from an increment of pi/2. What you really want to do is what I included below. Notice that if you have a square rotating inside another square, while the original square is constant in size, whatever is in the center and extends out to a center of the inner square will form a circle in it's rotation. If you take the outer square and divide it up into four equal areas and attach the four inner corners of the inner square to the edges of the outer square you will see that the offset of the inscribed cirlce of rotation from the upper left corner is exactly (.5outer_x-.5inner_x, .5outer_y-.5inner_y). If you have an image in the inner rect, you need to be careful to make sure that it exists entirely within the inscribed circle of rotation of the inner rectange. This is easy to do. The radius of this inscribed circle is exactly 1/2 the dimension of the original square. You can write something that does this with rectangles, but instead of a cirlce of rotation you will have an ellipse, and the implementation is a little more complex. There's no reason for that, since it should be a matter of gimp'ing your original image to make it into a square.

Good luck,
robert

import pygame
from pygame.locals import *
import time
import math

def load_image(name, colorkey=None):
try:
image = pygame.image.load(name)
except pygame.error, message:
print 'Cannot load image:', name
return None
image = image.convert()
if colorkey is not None:
if colorkey is -1:
colorkey = image.get_at((0,0))
image.set_colorkey(colorkey, RLEACCEL)
return image, image.get_rect()

def recentered(new, original):
new_rect = new.get_rect()
orig_rect = original.get_rect()
xoffset = new_rect[2]*.5-orig_rect[2]*.5
yoffset = new_rect[3]*.5-orig_rect[3]*.5
cropped_rect = new.subsurface((xoffset, yoffset, orig_rect[2], orig_rect[3]))
return cropped_rect

class orologio:
def __init__(self):
self.quadrante = pygame.display.set_mode((256,256))
self.original, self.rect = load_image('/home/dialtone/Documents/lancetta.jpg')
self.rect = (126, 0, self.rect[2], self.rect[3]) # Adjust rectangle
self.orig_rect = self.rect[:]
self.quadrante.blit(self.original, self.rect)

def update(self, degree):
self.degree = degree
self.image = pygame.transform.rotate(self.original, self.degree)
self.rect = self.image.get_rect()
self.image = recentered(self.image, self.original)
print self.image.get_rect(), self.rect
self.quadrante.blit(self.image, self.rect)
pygame.display.update()
pygame.time.wait(1000)

if __name__=='__main__':
pygame.init()
clock = orologio()
degrees = 0
quit = None
while not quit:
if abs(degrees) >= 360:
degrees = 0
clock.update(degrees)
degrees -= 6
for event in pygame.event.get():
if event.type == KEYDOWN:
print "posting quit"
pygame.event.post(pygame.event.Event(QUIT))
quit = 1