Pygame y Rotozoom Error!

Tratamos sobre el manejo de APIs frecuentemente utilizadas en el desarrollo de videojuegos, como SDL, pygame o SFML.

Pygame y Rotozoom Error!

Notapor programx » Lun Sep 03, 2012 9:29 am

Estoy haciendo pruebas en pygame (1.9.2a0 y python 2.7) y cuando intento usar pygame.transform.rotozoom, me lanza un error. Ya e probado con pygame.transform.scale y pygame.transform.rotate, funcionan perfectamente, pero no juntos, es decir, no puedo escalar una imagen y rotarla al mismo tiempo con estas dos funciones, por ese motivo es que quiero usar el rotozoom. Aqui esta el error que me lanzó python:

Fatal Python error: (pygame parachute) Segmentation Fault

This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information.


El codigo que estoy probando es este:

import pygame, sys

pygame.init()
pantalla = pygame.display.set_mode((500, 500))
pygame.display.set_caption("hola")

imagen_original = pygame.image.load("cuadro_verde.png").convert_alpha()
imagen = imagen_original

while True:
for eventos in pygame.event.get():
if eventos.type == pygame.QUIT:
sys.exit()
if eventos.type == pygame.KEYDOWN:
if eventos.key == pygame.K_F12:
sys.exit()

pantalla.blit(imagen, (200, 200))
imagen = pygame.transform.rotozoom(imagen_original, 45.0, 200.0)
pygame.display.flip()


Alguna ayuda?? :?:
Avatar de Usuario
programx
 
Mensajes: 34
Registrado: Mié Ago 03, 2011 4:46 am

Re: Pygame y Rotozoom Error!

Notapor Barajas » Lun Sep 03, 2012 2:33 pm

El problema esta en la función...

Código: Seleccionar todo
pygame.transform.rotozoom(imagen_original, 45.0, 200.0)


Precisamente en en ese 200, estas haciendo la imagen 200 VECES más grande, lo cual es mucho (en una imagen de 32x32 píxeles, seria una imagen de 6400x6400 píxeles), y aparte la rotación genera una imagen mucho mas grande, y para acabar, al colocarla dentro de bucle, quieres que te haga una imagen de esas dimensiones a cada ciclo... no me sorprende que quebrara :D

intenta con un valor mas pequeño como 2.0, o 5.0 y te darás cuenta de que en verdad la imagen crece mucho :).
Vi veri universum vivus vici
Avatar de Usuario
Barajas
 
Mensajes: 209
Registrado: Mar Nov 16, 2010 12:06 am

Re: Pygame y Rotozoom Error!

Notapor programx » Lun Sep 03, 2012 6:46 pm

Barajas escribió:El problema esta en la función...

Código: Seleccionar todo
pygame.transform.rotozoom(imagen_original, 45.0, 200.0)


Precisamente en en ese 200, estas haciendo la imagen 200 VECES más grande, lo cual es mucho (en una imagen de 32x32 píxeles, seria una imagen de 6400x6400 píxeles), y aparte la rotación genera una imagen mucho mas grande, y para acabar, al colocarla dentro de bucle, quieres que te haga una imagen de esas dimensiones a cada ciclo... no me sorprende que quebrara :D

intenta con un valor mas pequeño como 2.0, o 5.0 y te darás cuenta de que en verdad la imagen crece mucho :).


Hola Barajas, gracias por la solucion!, efectivamente era el valor descomunal que puse en la escala lo que provocaba el error, le bajé a 2.0 y agrando la imagen perfectamante junto con la rotacion de 45 grados. Y bueno lo coloco dentro del ciclo porque necesito cambiar los valores de escala y rotacion en tiempo real, ya que si no se actualizan constantemente, siempre se quedara en 45 y 2.0. Thanks!.
Avatar de Usuario
programx
 
Mensajes: 34
Registrado: Mié Ago 03, 2011 4:46 am

Re: Pygame y Rotozoom Error!

Notapor programx » Mié Sep 05, 2012 8:34 pm

Hey otra pregunta: como puedo rotar imagenes tomando como eje el centro de la imagen? e intentado modificando los valores center y topleft de los rectangulos como sigue:
rect.center = (rect.w/2, rect.h/2)
#tambien:
rect.topleft = rect.center

pero nada, gira de forma extraña, como si se tratara de un rueda cuadrada (si me entienden :) ), no me pareciera que tomara un eje inicial para rotar, ni siquiera la esquina superior izquierda.
Avatar de Usuario
programx
 
Mensajes: 34
Registrado: Mié Ago 03, 2011 4:46 am

Re: Pygame y Rotozoom Error!

Notapor Barajas » Jue Sep 06, 2012 3:58 am

Bien, mira el siguiente código:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

#---- función que dibuja la imagen en el centro ----#
def imagen_centro(pantalla, ima, pos):
#el centro de la imagen es lo que esta a la mitad de la misma
#por esa razón hay que restarle la mitad del alto y la mitad del ancho
#a la posición para ponerla en el centro.
#de hecho, creo que es igual al "rect.center"
w = ima.get_width()/2
h = ima.get_height()/2
x, y = pos
pantalla.blit( ima, ( x-w, y-h ) )


import pygame, sys

pygame.init()
pantalla = pygame.display.set_mode((500, 500))
pygame.display.set_caption("hola")

#cargamos la imagen....
imagen_original = pygame.image.load("tablet.png").convert_alpha()
imagen = imagen_original

#animar la rotación y el zoom
angulo = 0
dimension = 1
dz = 0.1

hacer = True
while hacer:
#fijo un máximo de frames
pygame.time.delay(1000/30)
for eventos in pygame.event.get():
if eventos.type == pygame.QUIT:
hacer = False
if eventos.type == pygame.KEYDOWN:
if eventos.key == pygame.K_F12:
hacer = False

pantalla.fill((100,100,100))
imagen_centro(pantalla,imagen,(250, 250))

imagen = pygame.transform.rotozoom(imagen_original, angulo, dimension)
#aumentamos el ángulo
angulo += 3
#se modifica la dimensión
dimension += dz
#si la dimensión es mayor a 5 o menor a un medio de la original
if dimension >= 5 or dimension <= 0.5:
#invertimos el sentido...
dz = -dz
pygame.display.flip()

pygame.quit()
sys.exit()


En realidad lo que se hace, es ampliar la imagen, y después colocarla en su centro, así parece que crece y gira con respecto a su centro, si corres el código, se logra ese efecto.
Espero que te sea útil :)
Vi veri universum vivus vici
Avatar de Usuario
Barajas
 
Mensajes: 209
Registrado: Mar Nov 16, 2010 12:06 am

Re: Pygame y Rotozoom Error!

Notapor programx » Vie Sep 07, 2012 9:09 pm

Barajas escribió:pygame.quit()
sys.exit()[/python]

En realidad lo que se hace, es ampliar la imagen, y después colocarla en su centro, así parece que crece y gira con respecto a su centro, si corres el código, se logra ese efecto.
Espero que te sea útil :)


Muy util Barajas! jeje :) . Reduje el codigo del ejemplo del chimpance para ver como rotaba, pero alli usan rectangulos y debido a esto el sprite no puede moverse mientras esta en rotacion, es por eso que cuando le pegas al mono, este se queda alli, dejando de avanzar. Esto pasa debido a que el rectangulo debe actualizarse constantemente a la nueva imagen rotada, impidiendo el movimiento.

Pero con tu ejemplo, al no usar rectangulos, puedo rotar y mover el sprite al mismo tiempo :) . Ahora tengo la duda con respecto al cambio de eje, pues e intentado modificar los valores de "w y h" en tu ejemplo y la imagen no gira en torno al eje indicado como deberia, sino que sigue girando como una rueda cuadrada (jaja).
Avatar de Usuario
programx
 
Mensajes: 34
Registrado: Mié Ago 03, 2011 4:46 am

Re: Pygame y Rotozoom Error!

Notapor Barajas » Sab Sep 08, 2012 1:58 am

programx escribió:Ahora tengo la duda con respecto al cambio de eje, pues e intentado modificar los valores de "w y h" en tu ejemplo y la imagen no gira en torno al eje indicado como debería, sino que sigue girando como una rueda cuadrada (jaja).


Pues no entiendo mucho de a que te refieres por girar en torno a un eje, por que si es lo que creo, en ese caso, son dos cosas diferentes...

Dejo a que pruebes el siguiente código, tal vez sirva para especificar...

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from math import *
#---- función que dibuja la imagen en el centro ----#
def imagen_centro(pantalla, ima, pos):
#el centro de la imagen es lo que esta a la mitad de la misma
#por esa razón hay que restarle la mitad del alto y la mitad del ancho
#a la posición para ponerla en el centro.
w = ima.get_width()/2
h = ima.get_height()/2
x, y = pos
pantalla.blit(ima,(x-w,y-h))
return (x-w,y-h)

#esto gira la imagen con respecto a un eje determinado...
def rotar_respecto_eje(pantalla, ima, eje, angulo, dx, dy):
aumx = cos(radians(angulo))*dx
aumy = sin(radians(angulo))*dy
x,y = eje
x+=aumx
y+=aumy
imagen_centro(pantalla, ima, (x,y))
return (x,y)

import pygame, sys

pygame.init()
pantalla = pygame.display.set_mode((500, 500))
pygame.display.set_caption("hola")

imagen_original = pygame.image.load("tablet.png").convert_alpha()
imagen = imagen_original

#animar la rotación y el zoom
angulo = 0
dimencion = 1
dz = 0.1

hacer = True
while hacer:
#fijo un máximo de frames
pygame.time.delay(1000/30)
for eventos in pygame.event.get():
if eventos.type == pygame.QUIT:
hacer = False
if eventos.type == pygame.KEYDOWN:
if eventos.key == pygame.K_F12:
hacer = False

pantalla.fill((100,100,100))
#imagen_centro(pantalla,imagen,(250, 250))
punto_centro = rotar_respecto_eje(pantalla, imagen, (250,250), angulo, 150, 150)
#
pygame.draw.line(pantalla,(20,20,20) ,(250,250),punto_centro,4)
#
imagen = pygame.transform.rotozoom(imagen_original, angulo, dimencion)
#aumentamos el ángulo
angulo += 3
#se modifica la dimensión
dimencion += dz
#si la dimensión es mayor a 5 o menor a un medio de la original
if dimencion >= 5 or dimencion <= 0.5:
#invertimos el sentido...
dz = -dz
pygame.display.flip()

pygame.quit()
sys.exit()
Vi veri universum vivus vici
Avatar de Usuario
Barajas
 
Mensajes: 209
Registrado: Mar Nov 16, 2010 12:06 am

Re: Pygame y Rotozoom Error!

Notapor programx » Vie Sep 14, 2012 5:57 am

Barajas escribió:
programx escribió:Ahora tengo la duda con respecto al cambio de eje, pues e intentado modificar los valores de "w y h" en tu ejemplo y la imagen no gira en torno al eje indicado como debería, sino que sigue girando como una rueda cuadrada (jaja).


Pues no entiendo mucho de a que te refieres por girar en torno a un eje, por que si es lo que creo, en ese caso, son dos cosas diferentes...

Dejo a que pruebes el siguiente código, tal vez sirva para especificar...



Bueno eso no era exactamente lo que queria hacer, pero me diste unas ideas con las funciones seno y coseno. Lo que quiero hacer exactamente es esto: http://subefotos.com/ver/?bd5a99c8556cb ... 1646do.png, es decir, si le indico a la imagen que su eje va a ser el centro de la misma imagen, esta deberia de girar en torno a este eje, y si por otro lado le digo que su eje va a ser la esquina inferior izquierda de la misma, deberia cambiar su forma de rotacion para adaptarse a este eje. De cualquier forma la imagen lo dice todo jeje.
Avatar de Usuario
programx
 
Mensajes: 34
Registrado: Mié Ago 03, 2011 4:46 am

Re: Pygame y Rotozoom Error!

Notapor Barajas » Sab Sep 15, 2012 6:44 am

Bien, eb ese caso ¿los ejes de rotación nunca saldrán de la imagen?, es decir, se mantendrán en sus limites (eso incluye a las esquinas).

Si es solo eso, creo que tengo la solución... (maldita trigonometría XD )
Vi veri universum vivus vici
Avatar de Usuario
Barajas
 
Mensajes: 209
Registrado: Mar Nov 16, 2010 12:06 am

Re: Pygame y Rotozoom Error!

Notapor programx » Sab Sep 15, 2012 5:03 pm

Barajas escribió:Bien, eb ese caso ¿los ejes de rotación nunca saldrán de la imagen?, es decir, se mantendrán en sus limites (eso incluye a las esquinas).

Si es solo eso, creo que tengo la solución... (maldita trigonometría XD )


Exacto, los ejes nunca salen de la imagen, el tipo de rotacion va a depender de donde se ubique el eje en la misma. Tambien estoy intentando flipear (voltear), escalar y rotar una imagen al mismo tiempo y no es posible, es decir, pygame.transform.flip y pygame.transform.rotozoom para que me realice las tres operaciones simultaneamente pero siempre se ejecuta la ultima unicamente, en este caso rotozoom nada mas y pareciera que no le hace caso al flip, igual si pongo flip de ultimo, pareciera que no le hace caso al rotozoom :evil: , esto de pygame para realizar estas operaciones es un lio, creo que voy a tener que utilizar una libreria opengl como rabbyt que me facilita este trabajo, pero me gustaria usar pygame puro :)
Avatar de Usuario
programx
 
Mensajes: 34
Registrado: Mié Ago 03, 2011 4:46 am

Re: Pygame y Rotozoom Error!

Notapor programx » Sab Sep 15, 2012 5:56 pm

Tengo la solucion de flipear, escalar y rotar al mismo tiempo, se debe usar primero la funcion rotozoom y luego la flip pero a esta ultima pasandole la misma imagen a transformar, ya que flip no se considera una funcion destructiva como rotozoom o rotate. Ahora, no entiendo por que no funciona si uso primero flip y despues rotozoom :idea:
Avatar de Usuario
programx
 
Mensajes: 34
Registrado: Mié Ago 03, 2011 4:46 am

Re: Pygame y Rotozoom Error!

Notapor Barajas » Sab Sep 15, 2012 8:36 pm

programx escribió: Lo que quiero hacer exactamente es esto: http://subefotos.com/ver/?bd5a99c8556cb ... 1646do.png


Bueno, creo que he conseguido lo de la imagen que gira respecto a un eje (en este caso, la esquina superior izquierda), es utilizando la magia de las matemáticas vectoriales :)

Aquí el código comentado:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from math import *


def rotar_respecto_esquina(pantalla, ima, pos, angulo, v_x, v_y):
#el punto de origen x, y
x, y = pos
#rotamos la imagen...
ima = pygame.transform.rotate(ima, angulo)
#sacamos el punto central de la imagen, que equivaldrá al origen
#de nuestro espacio vectorial
w = ima.get_width()/2
h = ima.get_height()/2
#rotamos el primer vector de referencia...
vect_1 = rota_vector(v_x,-angulo)
#rotamos el segundo vector de referencia...
vect_2 = rota_vector(v_y,angulo+90)
#y una vez han sido rotados... los sumamos, esta suma es el
#punto donde esta la esquina de nuestra imagen...
vect_suma = (vect_1[0]+vect_2[0],vect_1[1]+vect_2[1])
#el aumento en 'x', y en 'y' es igual sus componentes
au_x = vect_suma[0]
au_y = vect_suma[1]
#finalmente, el lugar donde es colocada la imagen para que paresca
#que gira respecto a su eje...
#restamos w, h, para colocarla al centro, y después, restamos
#el aumento en x, y, para colocarlo en su esquina...
pantalla.blit(ima, (x-w-au_x,y-h-au_y))
#y aquí la posición antes de moverlo...
#pantalla.blit(ima, (x-w,y-h))
#esto dibuja los vectores para que te hagas una idea :)
#el primer vector de referencia (verde)
pygame.draw.circle(pantalla,(20,200,20),
(x-int(vect_1[0]),y-int(vect_1[1])),
5)
#el segundo vector de referencia (azul)
pygame.draw.circle(pantalla,(20,20,200),
(x-int(vect_2[0]),y-int(vect_2[1])),
5)
#el vector resultado de la suma de los anteriores
pygame.draw.circle(pantalla,(200,20,20),
(x-int(vect_suma[0]),y-int(vect_suma[1])),
5)

#la función que rota los vectores respecto a un ángulo...
def rota_vector(vector, angulo):
au_x = vector[0]*cos(radians(angulo))-vector[1]*cos(radians(angulo))
au_y = vector[0]*sin(radians(angulo))+vector[1]*sin(radians(angulo))
nuevo = (au_x,au_y)
return nuevo

import pygame, sys

pygame.init()
pantalla = pygame.display.set_mode((500, 500))
pygame.display.set_caption("hola")

imagen_original = pygame.image.load("foto.png").convert_alpha()
imagen = imagen_original

#creo el par de vectores, que al sumarlos
#representan la esquina superior de la imagen
vector_x = [imagen.get_width()/2,0]
vector_y = [0,imagen.get_height()/2]
#animar la rotación y el zoom
angulo = 0
dimencion = 1
dz = 0.1
hacer = True
while hacer:
#fijo un máximo de frames
pygame.time.delay(1000/30)
for eventos in pygame.event.get():
if eventos.type == pygame.QUIT:
hacer = False
if eventos.type == pygame.KEYDOWN:
if eventos.key == pygame.K_F12:
hacer = False

pantalla.fill((100,100,100))
#coloco la imagen que gira con respecto a su esquina en el centro...
rotar_respecto_esquina(pantalla, imagen, (250,250), angulo, vector_x,vector_y)
#aumentamos el ángulo
angulo += 3
#se modifica la dimensión
dimencion += dz
#si la dimensión es mayor a 5 o menor a un medio de la original
if dimencion >= 5 or dimencion <= 0.5:
#invertimos el sentido...
dz = -dz
pygame.display.flip()

pygame.quit()
sys.exit()


Debes verlo funcionar.

Para cambiar la esquina o el punto donde gira, hay que modificar los vectores de referencia, de forma que su suma, sea igual al punto respecto al centro de la imagen, donde quieres que gire :)
Vi veri universum vivus vici
Avatar de Usuario
Barajas
 
Mensajes: 209
Registrado: Mar Nov 16, 2010 12:06 am

Re: Pygame y Rotozoom Error!

Notapor programx » Mié Sep 26, 2012 12:19 am

Barajas escribió:
programx escribió: Lo que quiero hacer exactamente es esto: http://subefotos.com/ver/?bd5a99c8556cb ... 1646do.png


Bueno, creo que he conseguido lo de la imagen que gira respecto a un eje (en este caso, la esquina superior izquierda), es utilizando la magia de las matemáticas vectoriales :)

Aquí el código comentado:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from math import *


def rotar_respecto_esquina(pantalla, ima, pos, angulo, v_x, v_y):
#el punto de origen x, y
x, y = pos
#rotamos la imagen...
ima = pygame.transform.rotate(ima, angulo)
#sacamos el punto central de la imagen, que equivaldrá al origen
#de nuestro espacio vectorial
w = ima.get_width()/2
h = ima.get_height()/2
#rotamos el primer vector de referencia...
vect_1 = rota_vector(v_x,-angulo)
#rotamos el segundo vector de referencia...
vect_2 = rota_vector(v_y,angulo+90)
#y una vez han sido rotados... los sumamos, esta suma es el
#punto donde esta la esquina de nuestra imagen...
vect_suma = (vect_1[0]+vect_2[0],vect_1[1]+vect_2[1])
#el aumento en 'x', y en 'y' es igual sus componentes
au_x = vect_suma[0]
au_y = vect_suma[1]
#finalmente, el lugar donde es colocada la imagen para que paresca
#que gira respecto a su eje...
#restamos w, h, para colocarla al centro, y después, restamos
#el aumento en x, y, para colocarlo en su esquina...
pantalla.blit(ima, (x-w-au_x,y-h-au_y))
#y aquí la posición antes de moverlo...
#pantalla.blit(ima, (x-w,y-h))
#esto dibuja los vectores para que te hagas una idea :)
#el primer vector de referencia (verde)
pygame.draw.circle(pantalla,(20,200,20),
(x-int(vect_1[0]),y-int(vect_1[1])),
5)
#el segundo vector de referencia (azul)
pygame.draw.circle(pantalla,(20,20,200),
(x-int(vect_2[0]),y-int(vect_2[1])),
5)
#el vector resultado de la suma de los anteriores
pygame.draw.circle(pantalla,(200,20,20),
(x-int(vect_suma[0]),y-int(vect_suma[1])),
5)

#la función que rota los vectores respecto a un ángulo...
def rota_vector(vector, angulo):
au_x = vector[0]*cos(radians(angulo))-vector[1]*cos(radians(angulo))
au_y = vector[0]*sin(radians(angulo))+vector[1]*sin(radians(angulo))
nuevo = (au_x,au_y)
return nuevo

import pygame, sys

pygame.init()
pantalla = pygame.display.set_mode((500, 500))
pygame.display.set_caption("hola")

imagen_original = pygame.image.load("foto.png").convert_alpha()
imagen = imagen_original

#creo el par de vectores, que al sumarlos
#representan la esquina superior de la imagen
vector_x = [imagen.get_width()/2,0]
vector_y = [0,imagen.get_height()/2]
#animar la rotación y el zoom
angulo = 0
dimencion = 1
dz = 0.1
hacer = True
while hacer:
#fijo un máximo de frames
pygame.time.delay(1000/30)
for eventos in pygame.event.get():
if eventos.type == pygame.QUIT:
hacer = False
if eventos.type == pygame.KEYDOWN:
if eventos.key == pygame.K_F12:
hacer = False

pantalla.fill((100,100,100))
#coloco la imagen que gira con respecto a su esquina en el centro...
rotar_respecto_esquina(pantalla, imagen, (250,250), angulo, vector_x,vector_y)
#aumentamos el ángulo
angulo += 3
#se modifica la dimensión
dimencion += dz
#si la dimensión es mayor a 5 o menor a un medio de la original
if dimencion >= 5 or dimencion <= 0.5:
#invertimos el sentido...
dz = -dz
pygame.display.flip()

pygame.quit()
sys.exit()


Debes verlo funcionar.

Para cambiar la esquina o el punto donde gira, hay que modificar los vectores de referencia, de forma que su suma, sea igual al punto respecto al centro de la imagen, donde quieres que gire :)


Man sin duda sabes como llevar las matematicas a la programacion jeje, esto es exactamente lo que intentaba hacer, me consto un poco entenderlo pero ya esta :) . Gracias Barajas por la excelente ayuda!.
Avatar de Usuario
programx
 
Mensajes: 34
Registrado: Mié Ago 03, 2011 4:46 am

Re: Pygame y Rotozoom Error!

Notapor shackra » Mar Nov 13, 2012 5:16 pm

bueno, creo que SFML (para python y C++) ya hacian esto!
http://openhelbreath.net/python-sfml2/ :P
Avatar de Usuario
shackra
 
Mensajes: 308
Registrado: Lun Jun 15, 2009 4:10 pm
Ubicación: Costa Rica


Volver a Sobre las bibliotecas multimedia

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado