luisoncpp

Animar matriz y flechas en Python

Apr 5th, 2021
983
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.49 KB | None | 0 0
  1. # https://note.nkmk.me/en/python-pillow-imagedraw/
  2. # https://pillow.readthedocs.io/en/stable/reference/ImageDraw.html
  3. from PIL import Image, ImageDraw, ImageFont
  4. import math
  5.  
  6. def MatrizUniforme(filas : int, col: int, val = ""):
  7.   mat = []
  8.   for i in range(filas):
  9.     mat.append([])
  10.     for k in range(col):
  11.       mat[i].append(val)
  12.   return mat
  13.  
  14. class EstiloMatriz:
  15.   largo_casilla = 32
  16.   alto_casilla = 32
  17.   offset = (10, 10)
  18.   bg_color = (255, 255, 255)
  19.   fg_color = (0, 0, 0)
  20.   fuente = ImageFont.truetype("FreeSerif.ttf", 20)
  21.   grosor = 2
  22.   def __init__(self, offset = (10, 10)):
  23.     self.offset = offset
  24.  
  25.   def col_x(self, col : int) -> int:
  26.     return self.offset[0] + col * self.largo_casilla
  27.  
  28.   def fila_y(self, fila : int) -> int:
  29.     return self.offset[1] + fila * self.alto_casilla
  30.  
  31.   def casilla_offset(self, fila : int, col: int) -> tuple:
  32.     return (self.col_x(col), self.fila_y(fila))
  33.  
  34.   def casilla_centro(self, fila : int, col: int) -> tuple:
  35.     offset = self.casilla_offset(fila, col)
  36.     return (offset[0] + self.largo_casilla / 2, offset[1] + self.alto_casilla / 2)
  37.  
  38. draw : ImageDraw
  39.  
  40. def DibujarMatriz(mat : list, estilo : EstiloMatriz):
  41.   num_filas = len(mat)
  42.   num_columnas = len(mat[0])
  43.  
  44.   largo_cuadricula = estilo.largo_casilla * num_columnas
  45.   alto_cuadricula = estilo.alto_casilla * num_filas
  46.  
  47.   corner_start = estilo.offset
  48.   corner_end = (corner_start[0] + largo_cuadricula, corner_start[1] + alto_cuadricula)
  49.  
  50.   def col_x(col : int) -> int:
  51.     return estilo.col_x(col)
  52.  
  53.   def fila_y(fila : int) -> int:
  54.     return estilo.fila_y(fila)
  55.  
  56.   def dibuja_fondo():
  57.     draw.rectangle(xy=(corner_start, corner_end), fill=estilo.bg_color, outline=estilo.fg_color, width = estilo.grosor)
  58.  
  59.   def dibuja_filas():
  60.     for i in range(num_filas):
  61.       inicio : tuple
  62.       fin : tuple
  63.       inicio = (corner_start[0], fila_y(i))
  64.       fin = (corner_end[0], fila_y(i))
  65.       draw.line(xy=(inicio, fin), fill = estilo.fg_color, width = estilo.grosor)
  66.  
  67.   def dibuja_columnas():
  68.     for i in range(num_columnas):
  69.       inicio : tuple
  70.       fin : tuple
  71.       inicio = (col_x(i), corner_start[1])
  72.       fin = (col_x(i), corner_end[1])
  73.       draw.line(xy=(inicio, fin), fill = estilo.fg_color, width = estilo.grosor)
  74.  
  75.   def dibuja_cuadricula():
  76.     dibuja_fondo()
  77.     dibuja_filas()
  78.     dibuja_columnas()
  79.  
  80.   def texto_en_casilla(fila : int, col : int)->str:
  81.     return mat[fila][col]
  82.  
  83.   def dibuja_texto_casilla(fila : int, col : int):
  84.     draw.text(xy = estilo.casilla_centro(fila, col), text = texto_en_casilla(fila, col), fill = estilo.fg_color, font = estilo.fuente, anchor = "mm")
  85.  
  86.   def dibuja_texto():
  87.     for i in range(num_filas):
  88.       for k in range(num_columnas):
  89.         dibuja_texto_casilla(i, k)
  90.  
  91.   dibuja_cuadricula()
  92.   dibuja_texto()
  93.  
  94. class EstiloFlecha:
  95.   ancho = 2
  96.   grosor_punta = 10
  97.   color = (0, 0, 255)
  98.  
  99. def ComplejoATupla(z : complex):
  100.   return (int(z.real), int(z.imag))
  101.  
  102. def DibujarFlecha(inicio : tuple, fin : tuple, estilo : EstiloFlecha):
  103.   draw.line(xy=(inicio, fin), fill = estilo.color, width = estilo.ancho)
  104.   direccion = complex(fin[0] - inicio[0] + (fin[1] - inicio[1])*1j)
  105.   direccion = direccion / abs(direccion)
  106.   o = complex(fin[0] + fin[1] * 1j)
  107.   ang = math.pi * (1.0 - 1.0/6.0)
  108.   turn = math.cos(ang) + math.sin(ang) * 1j
  109.   izq = o + direccion * turn * estilo.grosor_punta
  110.   der = o + direccion * turn.conjugate() * estilo.grosor_punta
  111.   draw.polygon(xy=(ComplejoATupla(o), ComplejoATupla(izq), ComplejoATupla(der)), fill = estilo.color, outline = estilo.color)
  112.  
  113. def DibujarFrame(mat : list, flechas = [], filtro = lambda i, k : True,
  114. estilo_matriz = EstiloMatriz(offset = (10, 10))) -> list:
  115.   mat_str = MatrizUniforme(len(mat), len(mat[0]))
  116.   global draw
  117.   for i in range(len(mat_str)):
  118.     for k in range(len(mat_str[i])):
  119.       if filtro(i, k):
  120.         mat_str[i][k] = str(mat[i][k])
  121.  
  122.   imagen = Image.new('RGB', (250, 250), (128, 128, 128))
  123.   draw = ImageDraw.Draw(imagen)
  124.   DibujarMatriz(mat_str, estilo_matriz)
  125.      
  126.   for f in flechas:
  127.     a = f[0]
  128.     b = f[1]
  129.     inicio_flecha = estilo_matriz.casilla_centro(fila = a[0], col = a[1])
  130.     fin_flecha = estilo_matriz.casilla_centro(fila = b[0], col = b[1])
  131.     DibujarFlecha(inicio_flecha, fin_flecha, EstiloFlecha())
  132.  
  133.   return imagen.convert("P", palette = Image.ADAPTIVE, colors = 256)
  134.  
  135. def GuardarGif(movie : list):
  136.   movie[0].save('movie.gif', save_all=True, append_images=movie[1:], optimize=True, duration=200, loop=0, include_color_table = True)
Advertisement
Add Comment
Please, Sign In to add comment