Advertisement
Guest User

Hexagon

a guest
Nov 7th, 2017
716
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.28 KB | None | 0 0
  1. import pygame
  2. import sys
  3. import time
  4. import random
  5. import numpy as np
  6. #import source.Game
  7. from pygame.locals import *
  8. import os
  9.  
  10. render_to_gif = False
  11.  
  12. def get_list_ind_to_len(data, goalsize, maxtry =5000):
  13. ## assume that the amounts of data are the statistics.
  14. # keys
  15. vv = [x for x in data]
  16. totalPaths = sum([data[x] for x in data])
  17. ## we will assume goalsize >> keys.
  18. ## we also will use a weighted average for our estimate of number of paths?
  19. weightAverage = np.sum(np.array([data[x]*x for x in data])/totalPaths)
  20. number_of_segements = int(goalsize/weightAverage)
  21. ## error in the number we will go with is sqrt(N) trakcs? Poisson?
  22. for i in range(maxtry):
  23. mytest = np.random.choice(vv, size=(np.random.poisson(number_of_segements)), p=(np.array([data[x] for x in data])/totalPaths))
  24. if sum(mytest) == goalsize:
  25. return mytest
  26. print("WE FAILED")
  27. return None
  28.  
  29. def intensity(i, total):
  30. ## return some value 0. -> 1.
  31. return float(total-i)/total
  32. return float(total-1*(4*i-(3*total)))/total
  33.  
  34. def project_3d_to_2d(v_pnts, o_pos, o_ang, e_vec = np.array([0,0,1])):
  35. r = (v_pnts.T - o_pos).T
  36. sx,sy,sz = tuple(np.sin(o_ang))
  37. cx,cy,cz = tuple(np.cos(o_ang))
  38. rot= np.array([[cz*cy,sz*cy,-sy],[cz*sy*sx-cx*sz, sz*sy*sx+cx*cz, sx*cy],[cz*cx*sy+sx*sz, sz*sy*cx-sx*cz, cx*cy]])
  39. d = np.matmul(rot, r)
  40. d2 = np.vstack([d, np.ones(d.shape[1])])
  41. f = np.matmul(np.array([[1,0,-e_vec[0]/e_vec[2], 0],
  42. [0,1,-e_vec[1]/e_vec[2], 0],
  43. [0, 0, 1, 0],
  44. [0, 0, 1/e_vec[2], 0]]), d2)
  45. fw = f[-1,:]+1e-10
  46. return np.vstack([f[0,:]/f[2,:], f[1,:]/f[2,:]]).T
  47.  
  48.  
  49. class HexPath:
  50. #Goal will be to uniquely enumerate (?) each hexagon path.
  51. ## then we can call on it in a pattern, or in random order?
  52. # we would want good enumeration... too. not redudnandt
  53. def __init__(self, center, size, basecolor = np.array([20,100,230]), max_len = 25, sphere_r = 50, sphere_angle = np.array([0,0]), linewidth = 10, path_override = None):
  54. self.sphere_r = sphere_r
  55. self.sphere_angle = sphere_angle
  56. self.center = center
  57. self.size = size
  58. self.max_len = max_len
  59. self.linewidth = linewidth
  60. self.basecolor = basecolor
  61. self.positions = [np.array([0,0])]
  62. self.deathcount = 0
  63. self.maxdeath = 10
  64. self.path_override = path_override
  65. self.path_step = 0
  66. self.path_substep = 1
  67. ## enumerate the grid as... (0,0) -> ( 0, 0), (1,0) -> ( a,0 ), (3*a, 0)
  68. # (0,1) -> (1.5*a, 0.866*a), (1,1) -> (2.5*a, 0.866*a ), 2,1 -> (4.5*a)
  69. # (0,2) -> ( 0, 1.732*a), (1,0) -> ( a, 1.732*a)
  70.  
  71. #0,1,3,4,6,7...
  72. #i+floor(i/2)
  73.  
  74. self.alive = True
  75. def step(self):
  76. if len(self.positions) >= self.max_len:
  77. self.alive = False
  78. if not self.alive:
  79. self.deathcount +=1
  80. if self.deathcount >= self.maxdeath:
  81. if self.path_override is None:
  82. temppos = self.positions
  83. self.__init__(self.center, self.size, self.basecolor, self.max_len, self.sphere_r, self.sphere_angle, self.linewidth)
  84. return temppos
  85. else:
  86. self.deathcount = 0
  87. self.path_step += 1
  88. self.path_substep = 1
  89. if self.path_step == len(self.path_override):
  90. self.path_step = 0
  91. self.positions = [self.path_override[self.path_step][0]]
  92. self.alive = True
  93. ## do death_procedure.
  94. return False
  95.  
  96. if self.path_override is not None:
  97. if self.path_substep == len(self.path_override[self.path_step]):
  98. if self.path_substep == self.max_len:
  99. self.alive = False
  100. else:
  101. self.alive = False
  102. self.deathcount += 1
  103. return False
  104. self.positions.append(self.path_override[self.path_step][self.path_substep])
  105. self.path_substep +=1
  106. return True
  107.  
  108. self.direction = np.arange(3)
  109. self.myPosition = self.positions[-1]
  110. posSet = set([tuple(x) for x in self.positions])
  111. #print(self.myPosition.shape)
  112. # -1, 0, 1
  113.  
  114. # neighbor of ( 0, 0) => ( 1, 0), (-1, 1), (-1,-1) : (-1,-1), ( 1, 0), (-1, 1)
  115. # neighbor of ( 1, 0) => ( 0, 0), ( 0, 1), ( 0,-1) : (-1,-1), (-1, 0), (-1, 1)
  116. # neighbor of ( 0, 1) => ( 1, 0), ( 1, 2), ( 1, 1) : ( 1,-1), ( 1, 0), ( 1, 1)
  117. # neighbor of ( 1, 1) => ( 2, 2), ( 0, 1), ( 2, 0) : ( 1,-1), (-1, 0), ( 1, 1)
  118.  
  119. self.test_y = self.direction-1
  120. self.test_x = np.where(self.direction-1 == 0, (1-2*(self.myPosition[0]%2)), (1-2*(1-self.myPosition[1]%2)))
  121.  
  122. self.tempPos = self.myPosition+np.vstack((self.test_x, self.test_y)).T
  123. np.random.shuffle(self.tempPos)
  124.  
  125. for point in self.tempPos:
  126. if tuple(point) in posSet:
  127. continue
  128. self.positions.append(point)
  129. return True
  130.  
  131. self.alive = False
  132. return False
  133. def get_pos(self, rotation = 0, t= 0):
  134. self.hexiPathRect = np.array(self.positions, dtype='float64')
  135. pos = np.array(self.positions)
  136. self.xpoints = pos[:,0].astype('float64')
  137. self.ypoints = pos[:,1].astype('float64')
  138. self.hexiPathRect[:,0][pos[:,1]%2 == 0] = self.size*(np.floor(pos[:,0][pos[:,1]%2 == 0]/2)+pos[:,0][pos[:,1]%2 == 0])
  139. self.hexiPathRect[:,0][pos[:,1]%2 == 1] = self.size*(1.5+np.floor(pos[:,0][pos[:,1]%2 == 1]/2)+pos[:,0][pos[:,1]%2 == 1])
  140. self.hexiPathRect[:,1] = 0.86602540378*self.size*pos[:,1]
  141. #self.hexiPathRect += self.center
  142. if rotation == 0:
  143. return self.hexiPathRect+self.center
  144. #rotation = 0
  145. xy = np.matmul(np.array([[np.cos(rotation), -np.sin(rotation)],
  146. [np.sin(rotation), np.cos(rotation)]]), self.hexiPathRect.T).T+self.center
  147. #xy = self.hexiPathRect
  148. #sphere_r = 80.*np.cos(t/8)#10.+80.*(np.cos(t/12.))**2
  149. sphere_r = np.abs(self.sphere_r)
  150. r, theta = np.sqrt(xy[:,0]**2+xy[:,1]**2)/(4*np.pi*sphere_r), np.arctan2(xy[:,1], xy[:,0])
  151.  
  152. my3d = sphere_r*np.vstack([np.sin(r)*np.cos(theta),np.sin(r)*np.sin(theta),np.sign(self.sphere_r)*np.cos(r)])
  153.  
  154. cx,cy = tuple(np.cos(self.sphere_angle))
  155. sx,sy = tuple(np.sin(self.sphere_angle))
  156.  
  157. rrmat = np.array([[cy , -sy, 0.],
  158. [cx*sy, cx*cy, -sx],
  159. [sx*sy, cy*sx, cx]])
  160.  
  161. my3d = np.matmul(rrmat, my3d)
  162. rotation *= float(1+int(sphere_r/30))
  163.  
  164. #test = project_3d_to_2d(np.hstack([xy, np.zeros((xy.shape[0],1)) ]).T, np.array([0,0,-500]), np.array([0,0,0]))
  165. test = project_3d_to_2d(my3d, np.array([np.sin(rotation)*500,0,500*np.cos(rotation)]), np.array([0,rotation,0]))
  166. #test = project_3d_to_2d(my3d, np.array([0,0,-100]), np.array([0,0,0]))
  167. return test*np.array([4000,4000])+np.array([(1920/2,1080/2)])
  168. def draw(self, surface, rotation = 0, draw_action=True, t=0):
  169. posToDraw = self.get_pos(rotation = rotation, t = t)
  170.  
  171. #cv = self.basecolor*intensity(len(self.positions), self.max_len)
  172. widths = self.linewidth*intensity(self.deathcount, self.maxdeath)#len(self.positions), self.max_len+5)
  173. intss = int(100*intensity(self.deathcount, self.maxdeath))
  174. returnvals = {}
  175. count = 0
  176. for xy0,xy1 in zip(posToDraw[:-1], posToDraw[1:]):
  177. #maxlen = self.max_len
  178. #color = self.basecolor *(1. if count < maxlen/2 else float(maxlen/2-(count-maxlen/2)/(maxlen/2)))
  179. cv = pygame.Color(0,0,0)
  180. #amp = (100-amp)*0.75
  181. #h1 = int(count*360/(2*self.max_len)+(20*t*360./250))%360
  182. h1 = int(count*360/(1*self.max_len)+(1*t*360./250))%360
  183.  
  184. #x0 = 120*np.cos(-t*2*np.pi*0.01)+(1920/2)
  185. #y0 = 120*np.sin(-t*2*np.pi*0.01)+(1080/2)
  186. #r0 = np.array([x0,y0])
  187. #pos = np.array([(xy0[0]+xy1[0])/2, (xy0[1]+xy1[1])/2])
  188. #hpos = int(np.sqrt(np.sum((r0-pos)**2))*2)%360
  189. #hh = int(h1*np.cos(2*np.pi*t/100.)**2+hpos*np.sin(2*np.pi*t/250)**2)%360
  190.  
  191. cv.hsva = (h1,65,intss,intss)
  192. ## let's add the spatial color thing...
  193. #cv = get_spatial_color((xy0[0]+xy1[0])/2, (xy0[1]+xy1[1])/2, t, intss)
  194. if draw_action:
  195. pygame.draw.line(surface, cv, tuple(xy0), tuple(xy1), int(widths))
  196. else:
  197. returnvals[(tuple(xy0), tuple(xy1))] = (cv, int(widths))
  198. count +=1
  199. return returnvals
  200.  
  201.  
  202. def draw_all(surface, myset):
  203. for key in myset:
  204. pygame.draw.line(surface, myset[key][0], key[0], key[1], myset[key][1])
  205.  
  206. def draw_list_hex(surface, list_of_hex, rotation = 0, t= 0):
  207. #[x.draw(surface, rotation, True, t) for x in list_of_hex]
  208. #return 0
  209. ## 1/3rd (0.058)
  210. listofpoints = [x.draw(surface, rotation, False, t) for x in list_of_hex]
  211. st = time.time()
  212. myset = {}
  213. for singset in listofpoints:
  214. for key in singset:
  215. if key in myset:
  216. if myset[key][1] < singset[key][1]:
  217. myset[key] = singset[key]
  218. continue
  219. if (key[1], key[0]) in myset:
  220. if myset[(key[1], key[0])][1] < singset[key][1]:
  221. myset[(key[1], key[0])] = singset[key]
  222. continue
  223. myset[key] = singset[key]
  224.  
  225. draw_all(surface,myset)
  226.  
  227. def get_spatial_color(x,y,t,amp):
  228. x0 = 120*np.cos(-t*2*np.pi*0.01)+(1920/2)
  229. y0 = 120*np.sin(-t*2*np.pi*0.01)+(1080/2)
  230. r0 = np.array([x0,y0])
  231. pos = np.array([x,y])
  232. #h = (int(360.+(180.*np.cos(np.sum((r0-pos)**2)*2*np.pi/(1000)))))%360
  233. h = int(np.sqrt(np.sum((r0-pos)**2))*2)%360
  234.  
  235. #h = (10*t+int(360.+(180.*np.cos(np.sum((r0-pos)**2)*2.*np.pi/(1000.)))))%360
  236. #print(h)
  237. #h = (360*np.exp(-float((x-x0)**2+(y-y0)**2)/(2*100**2)))%360
  238. temp = pygame.Color(0,0,0)
  239. #amp = (100-amp)*0.75
  240. temp.hsva = (h,65,amp,amp)
  241. return temp
  242.  
  243. if __name__ == "__main__":
  244. pygame.mixer.pre_init()#22050, 16, 2, 256)
  245. pygame.font.init()
  246. pygame.init()
  247. font = pygame.font.Font(None, 36)
  248.  
  249. os.environ['SDL_VIDEO_WINDOW_POS'] = "0,0"
  250. screen = pygame.display.set_mode((1920, 1080), pygame.DOUBLEBUF | pygame.DOUBLEBUF | pygame.HWSURFACE |pygame.NOFRAME)#, pygame.FULLSCREEN))
  251. #source.Game.Game().main(screen)
  252.  
  253.  
  254. fpsClock=pygame.time.Clock()
  255.  
  256. surface = pygame.Surface(screen.get_size())
  257. surface = surface.convert()
  258. surface.fill((255,255,255))
  259.  
  260. pygame.key.set_repeat(1, 40)
  261.  
  262. screen.blit(surface, (0,0))
  263. pygame.display.flip()
  264.  
  265. #rangles = np.random.uniform(0,np.pi*2, size=(2,4))
  266. rangles = np.array([[0,np.pi,0,np.pi],[np.pi,np.pi,0,0]])
  267. hexagon_paths = []
  268. stored_vals = []
  269.  
  270.  
  271. huge_path_list = {}
  272. deathsize = 9
  273. for jkj in range(20*100):
  274. pp = HexPath(np.array([0,0]), 1, max_len = 25)
  275. tt = pp.step()
  276. count = 0
  277. while type(tt) is bool:
  278. tt = pp.step()
  279. count+=1
  280. if count > 100:
  281. print(pp.positions)
  282. print("what.")
  283. sys.exit(0)
  284. ## tt is now not a bool, it has died. we have a position.
  285. if (len(tt)+deathsize) in huge_path_list:
  286. huge_path_list[len(tt)+deathsize].append(tt)
  287. else:
  288. huge_path_list[len(tt)+deathsize] = [tt]
  289.  
  290. #print(len(huge_path_list))
  291. #for key in huge_path_list:
  292. # print(key, len(huge_path_list[key]))
  293. size_path_list = {}
  294. for key in huge_path_list:
  295. size_path_list[key] = len(huge_path_list[key])
  296.  
  297. attempts = []
  298. for i in range(40):
  299. attempt = get_list_ind_to_len(size_path_list, 1000)
  300. if attempt is None:
  301. #print("Couldn't find a good permutation for repetitive")
  302. continue
  303. attempts.append(attempt)
  304. if len(attempts) == 0:
  305. print("No Permutations AT ALL?!?")
  306. sys.exit(0)
  307.  
  308. numpaths = 40
  309.  
  310. mysolutions = []
  311. for i in range(numpaths):
  312. thissol = []
  313. attempt = attempts[np.random.choice(len(attempts))]
  314. np.random.shuffle(attempt)
  315. for size in attempt:
  316. thissol.append(huge_path_list[size][np.random.choice(size_path_list[size])])
  317. mysolutions.append(thissol)
  318.  
  319. #print(sum([len(x) for x in mysolutions[0]]))
  320. #print(len(mysolutions[0]))
  321. #print(sum([1 for x in mysolutions[0] if len(x) < 25]))
  322. ## verify mysolution[0] is valid
  323. #testpath = HexPath(np.array([0,0]), 1, path_override = mysolutions[0])
  324. #mylist = []
  325. #for i in range(5500):
  326. # if testpath.path_step == 0 and testpath.path_substep == 1:
  327. # print(i)
  328. # testpath.step()
  329.  
  330. s2 = np.random.choice(len(huge_path_list[25]), size=1)
  331. special_test = [huge_path_list[25][i] for i in s2]
  332.  
  333. for i, special_test in enumerate(mysolutions):
  334. ss = 30 if (i < int(numpaths/2)) else 60#15-10*int(i/30)
  335. sv = 60 if (i < int(numpaths/2)) else 80
  336. hexagon_paths.append(HexPath(np.array([0,0]), sv, max_len = 25, sphere_r = ss, sphere_angle = rangles[:,int(i/(numpaths/4))], linewidth=5, path_override = special_test)) #
  337.  
  338. #hexagon_paths.append(HexPath(np.array([40,.866*80.]), 80., sphere_r =50))
  339. #hexagon_paths.append(HexPath(np.array([0,0]), 80., sphere_r = 10+2*i))
  340. [x.step() for x in hexagon_paths]
  341. #stored_vals.append([x.positions[-1] for x in hexagon_paths])
  342. #hexagon_paths = [x if x.alive else HexPath(np.array([0,0]), 30.) for x in hexagon_paths]
  343.  
  344. #print(stored_vals[-1])
  345. #print(stored_vals[0])
  346. #hexagon_paths = [ for x in range(100)]
  347.  
  348. lasttime = time.clock()
  349. running = True
  350. t = 0
  351. #rangles = np.random.uniform(-0.01,0.01, size=(2,6))
  352. rangles = np.random.uniform(0,0, size=(2,4))
  353. while running:
  354.  
  355. for event in pygame.event.get():
  356. if event.type == QUIT:
  357. pygame.quit()
  358. running = False
  359. sys.exit(0)
  360. elif event.type == KEYDOWN:
  361. if event.key == K_ESCAPE:
  362. pygame.quit()
  363. running = False
  364. sys.exit(0)
  365.  
  366. #pressedList = pygame.key.get_pressed()
  367. #if pressedList[K_UP]or pressedList[K_w]:
  368.  
  369. surface.fill((0,0,0))
  370.  
  371. #for x in hexagon_paths:
  372. # x.draw(surface, t/100.)
  373. draw_list_hex(surface, hexagon_paths, 2*np.pi*3*t/1000., t)
  374.  
  375. [x.step() for x in hexagon_paths]
  376.  
  377. #rangles = np.random.uniform(-0.05,0.05, size=(2,4))
  378. for i,hex_path in enumerate(hexagon_paths):
  379. if i >= numpaths/2:
  380. hex_path.size = 70+10*np.cos(2*np.pi*(t*16.)/1000) #np.sign(hex_path.sphere_r)*(60+10*np.cos(t/0.05))
  381. hex_path.sphere_angle += rangles[:,int(i/(numpaths/4))]
  382.  
  383. #hexagon_paths.append(HexPath(np.array([0,0]), 80., sphere_r = ss, sphere_angle = rangles[:,int(i/40)]))
  384.  
  385. #hexagon_paths.append(HexPath(np.array([40,.866*80.]), 80., sphere_r =50))
  386. #hexagon_paths.append(HexPath(np.array([0,0]), 80., sphere_r = 10+2*i))
  387.  
  388. sizevals = 70+60*np.sin(2*np.pi*(t*32)/1000)
  389. #for x in hexagon_paths:
  390. # x.size = sizevals
  391. #hexagon_paths = [x if x.alive else for x in hexagon_paths]
  392. screen.blit(surface, (0,0))
  393.  
  394.  
  395. nowtime = time.clock()
  396.  
  397. if (nowtime-lasttime) < 1./60:
  398. time.sleep(1./60-(nowtime-lasttime))
  399. lasttick = 1./(time.clock()-lasttime)
  400. lasttime = nowtime
  401.  
  402. pygame.display.update()
  403. if render_to_gif:
  404. if t >=1:
  405. if t%10 == 0:
  406. print(t)
  407. pygame.image.save(screen, "render/image_%04d.bmp"%(t))
  408. if t > 1005:
  409. sys.exit(0)
  410. t+=1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement