kopia lustrzana https://github.com/villares/sketch-a-day
				
				
				
			
		
			
				
	
	
		
			125 wiersze
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			125 wiersze
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Python
		
	
	
| #*- coding: utf-8 -*-
 | ||
| 
 | ||
| from __future__ import division, print_function
 | ||
| from random import sample, choice
 | ||
| 
 | ||
| 
 | ||
| class Grid():
 | ||
| 
 | ||
|     def __init__(self, graph, cols, rows, mode=0):
 | ||
|         """
 | ||
|         mode 0: heavy center
 | ||
|         mode 1: heavy perifery
 | ||
|         """
 | ||
|         self.cols = cols
 | ||
|         self.rows = rows
 | ||
|         self.graph = graph
 | ||
|         self.grid = self.generate_points(mode)
 | ||
|         self.other_grid = self.generate_points(mode)
 | ||
| 
 | ||
|     def generate_points(self, mode):
 | ||
|         points = []
 | ||
|         for i in range(self.cols * self.rows):
 | ||
|             x = i % self.cols
 | ||
|             y = i // self.rows
 | ||
|             points.append([x, y])
 | ||
|         p_dist = lambda p: dist(p[0], p[1], self.cols / 2, self.rows / 2)
 | ||
|         points = sorted(points, key=p_dist)
 | ||
|         if mode == 0:
 | ||
|             v_list = reversed(sorted(self.graph.vertices(),
 | ||
|                                      key=self.graph.vertex_degree))
 | ||
|         elif mode == 1:
 | ||
|             v_list = sorted(self.graph.vertices(),
 | ||
|                             key=self.graph.vertex_degree)
 | ||
|         else:
 | ||
|             v_list = self.graph.vertices()
 | ||
|             print("random mode")
 | ||
| 
 | ||
|         return {v: p for v, p in zip(v_list, points)}
 | ||
| 
 | ||
|     def __getitem__(self, k):
 | ||
|         return self.grid[k]
 | ||
| 
 | ||
|     def __setitem__(self, k, v):
 | ||
|         self.grid[k] = v
 | ||
| 
 | ||
|     def __len__(self):
 | ||
|         return len(self.grid)
 | ||
| 
 | ||
|     def keys(self):
 | ||
|         return self.grid.keys()
 | ||
| 
 | ||
|     def values(self):
 | ||
|         return self.grid.values()
 | ||
| 
 | ||
|     def __iter__(self):
 | ||
|         return iter(self.grid)
 | ||
| 
 | ||
|     def swap(self, num=2):
 | ||
|         grid = self.grid
 | ||
|         graph = self.graph
 | ||
|         fail = 0
 | ||
|         n = m = self.edge_distances()
 | ||
|         while m <= n and fail < len(graph) ** 2:
 | ||
|             new_grid = dict(grid)
 | ||
|             if num == 2:
 | ||
|                 a, b = sample(graph.vertices(), 2)
 | ||
|                 new_grid[a], new_grid[b] = new_grid[b], new_grid[a]
 | ||
|             else:
 | ||
|                 ks = sample(graph.vertices(), num)
 | ||
|                 vs = [grid[k] for k in sample(ks, num)]
 | ||
|                 for k, v in zip(ks, vs):
 | ||
|                     new_grid[k] = v
 | ||
|             n = self.edge_distances(new_grid)
 | ||
|             if m > n:
 | ||
|                 t = "{:.2%} at: {} tries of {}v shuffle/swap" \
 | ||
|                     .format((n - m) / m, fail + 1, num)
 | ||
|                 print("\n" + t, end="")
 | ||
|                 self.grid = new_grid
 | ||
|             else:
 | ||
|                 fail += 1
 | ||
|         print(".", end='')
 | ||
| 
 | ||
| 
 | ||
|     def edge_distances(self, ng=None):
 | ||
|         grid = ng or self.grid
 | ||
|         total = 0
 | ||
|         for edge in self.graph.edges():
 | ||
|             if len(edge) == 2:
 | ||
|                 a, b = edge
 | ||
|                 xa, ya = grid[a]
 | ||
|                 xb, yb = grid[b]
 | ||
|                 d = dist(xa, ya, xb, yb)
 | ||
|                 total += d
 | ||
|         return total
 | ||
| 
 | ||
|     def edges(self, t):
 | ||
|         z = zip(self.sorted_edges(self.grid),
 | ||
|                 self.sorted_edges(self.other_grid))
 | ||
|         lerped_edges = []
 | ||
|         for za, zb in z:
 | ||
|             lerped_edges.append([lerp(ea, eb, t)
 | ||
|                                  for ea, eb in zip(za, zb)])
 | ||
|         return lerped_edges
 | ||
| 
 | ||
|     def sorted_edges(self, grid):
 | ||
|         edgs = []
 | ||
|         for e in self.graph.edges():
 | ||
|             if len(e) == 2:
 | ||
|                 a, b = tuple(e)
 | ||
|                 xa, ya = grid[a]
 | ||
|                 xb, yb  = grid[b]
 | ||
|                 da = self.graph.vertex_degree(a)
 | ||
|                 db = self.graph.vertex_degree(b)
 | ||
|                 deg = ((da + db) / 2)  # r / (Grid.w / 10)
 | ||
|                 edgs.append((xa, ya, xb, yb, da, db, deg))
 | ||
|         return sorted(edgs, key=lambda e: e[6])
 | ||
| 
 | ||
| def dim_grid(n):
 | ||
|     a = int(sqrt(n))
 | ||
|     b = n // a
 | ||
|     if a * b < n:
 | ||
|         b += 1
 | ||
|     print(u'{}: {} × {} ({})'.format(n, a, b, a * b))
 | ||
|     return a, b
 |