drandreasdr

Walkingsquaresinbox_walkingsquaresinbox.py

Nov 23rd, 2014
236
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.43 KB | None | 0 0
  1. #squares walking on and in squares
  2. __author__ = 'drandreasdr'
  3. import numpy as np
  4. import math
  5. import pygame
  6. from pygame import gfxdraw
  7. math.tau = 2*math.pi
  8.  
  9. colorwhite = (255, 255, 255)
  10. colorblack = (0, 0, 0)
  11.  
  12. class WalkingSquaresInBox:
  13.     def __init__(self, animationrect, period):
  14.         self.animationrect = animationrect
  15.         self.period = period
  16.  
  17.         #Numbers of cycles (i.e. 90 degree turns):
  18.         self.ncyclesA = 8
  19.         self.ncyclesB = 8*3
  20.         #self.ncyclesABcontact = 8*3/2
  21.  
  22.         #Periods:
  23.         ##Time of one 90 degree rotation of A and B, resp:
  24.         self.periodA = self.period/self.ncyclesA
  25.         self.periodB = self.period/self.ncyclesB
  26.         ##Time during which a pair of corners in A and B are in contact:
  27.         self.periodABcontact = self.periodB*2
  28.  
  29.         #Rotation angles in one period:
  30.         self.rotAngleA = math.tau/4
  31.  
  32.         #Global time for animation: (repeats after the time "self.period")
  33.         self.elapsedtime = 0
  34.  
  35.         #Geometry:
  36.         self.sidelength = self.animationrect.width/3
  37.  
  38.         #Predetermined stuff:
  39.         ##List of A-ground contact points positions and indices, and initial angles, respectively:
  40.         self.indA_cAg_list = np.cumsum([0, 2, 1, 2, 1, 2, 1, 2]) % 4
  41.         posx_cAg_list = self.animationrect.left + self.sidelength*np.array([2, 3, 3, 2, 1, 0, 0, 1])
  42.         posy_cAg_list = self.animationrect.top + self.sidelength*np.array([3, 2, 1, 0, 0, 1, 2, 3])
  43.         self.pos_cAg_list = np.array([posx_cAg_list, posy_cAg_list]).T
  44.         self.alpha0_list = math.tau/4*(np.array([1, 2, 2, 3, 3, 4, 4, 1]) % 4)
  45.  
  46.     def tick(self, dt):
  47.         #Advance time:
  48.         self.elapsedtime = (self.elapsedtime + dt) % self.period
  49.  
  50.     def draw(self, displaysurface):
  51.         #Count number of periods elapsed and measure time current ones have lasted:
  52.         nelapsedperiodsA, elapsedtimeA = divmod(self.elapsedtime, self.periodA)
  53.         nelapsedperiodsAB, elapsedtimeABcontact = divmod(self.elapsedtime, self.periodABcontact)
  54.  
  55.         #Indices, angles, positions depending on the above:
  56.         ##For square A:
  57.         indA_cAg = self.indA_cAg_list[nelapsedperiodsA]
  58.         pos_cAg = self.pos_cAg_list[nelapsedperiodsA, :]
  59.  
  60.         alpha0 = self.alpha0_list[nelapsedperiodsA]
  61.         alpharel = self.rotAngleA*elapsedtimeA/self.periodA
  62.         alpha = (alpha0 - alpharel) % math.tau
  63.         ###Help objects:
  64.         unitvectorA = np.array([math.cos(alpha), -math.sin(alpha)])
  65.         unitvectorAperp = np.array([math.cos(alpha + math.tau/4), -math.sin(alpha + math.tau/4)])
  66.         pos_cornersA_list = np.zeros([4, 2])
  67.         pos_cornersA_list[indA_cAg] = pos_cAg
  68.         pos_cornersA_list[(indA_cAg + 1) % 4] = pos_cAg + self.sidelength*unitvectorA
  69.         pos_cornersA_list[(indA_cAg + 2) % 4] = pos_cAg + self.sidelength*(unitvectorA + unitvectorAperp)
  70.         pos_cornersA_list[(indA_cAg + 3) % 4] = pos_cAg + self.sidelength*unitvectorAperp
  71.         ##For square B:
  72.         indA_cAB = (2 + nelapsedperiodsAB) % 4
  73.         pos_cAB = pos_cornersA_list[indA_cAB, :]
  74.         beta0 = (alpha + math.tau/2 + math.tau/4*((indA_cAB - indA_cAg - 1) % 4)) % math.tau
  75.         betarel = math.tau/2*elapsedtimeABcontact/self.periodABcontact
  76.         beta = (beta0 + betarel) % math.tau
  77.         ###Help objects:
  78.         unitvectorB = np.array([math.cos(beta), -math.sin(beta)])
  79.         unitvectorBperp = np.array([math.cos(beta + math.tau/4), -math.sin(beta + math.tau/4)])
  80.         pos_cornersB_list = np.array([pos_cAB,
  81.                                       pos_cAB + self.sidelength*unitvectorB,
  82.                                       pos_cAB + self.sidelength*(unitvectorB + unitvectorBperp),
  83.                                       pos_cAB + self.sidelength*unitvectorBperp])
  84.         ###(note: I don't care about consistency in numbering of square B:s corners between AB-periods)
  85.  
  86.         #Draw:
  87.         pos_cornersA_int_list = [[int(y) for y in x] for x in pos_cornersA_list.tolist()]
  88.         pos_cornersB_int_list = [[int(y) for y in x] for x in pos_cornersB_list.tolist()]
  89.         pygame.draw.rect(displaysurface, colorwhite, self.animationrect, 0)
  90.         gfxdraw.aapolygon(displaysurface, pos_cornersA_int_list, colorblack)
  91.         gfxdraw.aapolygon(displaysurface, pos_cornersB_int_list, colorblack)
  92.         gfxdraw.filled_polygon(displaysurface, pos_cornersA_int_list, colorblack)
  93.         gfxdraw.filled_polygon(displaysurface, pos_cornersB_int_list, colorblack)
Advertisement
Add Comment
Please, Sign In to add comment