refactor load/save functions
Use streams instead of filename. Move load/write functions if modules where logical.
This commit is contained in:
parent
6bdab7d667
commit
c37cce25ed
5 changed files with 160 additions and 130 deletions
47
graph.py
Normal file
47
graph.py
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
|
||||
from geometry import x,y
|
||||
|
||||
def graph_of( segments ):
|
||||
graph = {}
|
||||
for start,end in segments:
|
||||
graph[start] = graph.get( start, [] )
|
||||
graph[start].append( end )
|
||||
graph[end] = graph.get( end, [] )
|
||||
graph[end].append( start )
|
||||
return graph
|
||||
|
||||
|
||||
def edges_of( graph ):
|
||||
edges = set()
|
||||
for k in graph:
|
||||
for n in graph[k]:
|
||||
if k != n and (k,n) not in edges and (n,k) not in edges:
|
||||
edges.add( (k,n) )
|
||||
return list(edges)
|
||||
|
||||
|
||||
def nodes_of( graph ):
|
||||
return graph.keys()
|
||||
|
||||
|
||||
def load( stream ):
|
||||
graph = {}
|
||||
for line in stream:
|
||||
if line.strip()[0] != "#":
|
||||
skey,svals = line.split(":")
|
||||
key = tuple((float(i) for i in skey.split(',')))
|
||||
graph[key] = []
|
||||
for sp in svals.split():
|
||||
p = tuple(float(i) for i in sp.split(","))
|
||||
assert(len(p)==2)
|
||||
graph[key].append( p )
|
||||
return graph
|
||||
|
||||
|
||||
def write( graph, stream ):
|
||||
for k in graph:
|
||||
stream.write( "%f,%f:" % (x(k),y(k)) )
|
||||
for p in graph[k]:
|
||||
stream.write( "%f,%f " % (x(p),y(p)) )
|
||||
stream.write("\n")
|
||||
|
||||
79
run_all.py
79
run_all.py
|
|
@ -17,6 +17,7 @@ import shortpath
|
|||
import lindenmayer
|
||||
import triangulation
|
||||
import voronoi
|
||||
import graph
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
|
|
@ -53,7 +54,8 @@ penrose_segments = set()
|
|||
|
||||
if args.penrose:
|
||||
LOGN( "Load the penrose tiling" )
|
||||
penrose_segments = utils.load_segments(args.penrose)
|
||||
with open(args.penrose) as fd:
|
||||
penrose_segments = utils.load_segments(fd)
|
||||
|
||||
else:
|
||||
LOGN( "Draw the penrose tiling" )
|
||||
|
|
@ -79,11 +81,11 @@ else:
|
|||
penrose.draw( depth )
|
||||
|
||||
# save this intermediate step
|
||||
LOGN( "\tsegments",len(penrose.segments) )
|
||||
with open("d%i_penrose.segments" % depth, "w") as fd:
|
||||
fd.write( str(penrose) )
|
||||
|
||||
penrose_segments = penrose.segments
|
||||
LOGN( "\tsegments",len(penrose_segments) )
|
||||
with open("d%i_penrose.segments" % depth, "w") as fd:
|
||||
utils.write_segments( penrose_segments, fd )
|
||||
|
||||
|
||||
|
||||
########################################################################
|
||||
|
|
@ -94,7 +96,8 @@ trajs = []
|
|||
|
||||
if args.tour != [None]:
|
||||
for tour in args.tour:
|
||||
trajs.append( utils.load_points(tour) )
|
||||
with open(tour) as fd:
|
||||
trajs.append( utils.load_points(fd) )
|
||||
|
||||
if args.notsp:
|
||||
if args.tour == [None] or not args.pheromones:
|
||||
|
|
@ -102,13 +105,14 @@ if args.notsp:
|
|||
sys.exit(error_codes["NO-TSP"])
|
||||
|
||||
if args.pheromones:
|
||||
phero = utils.load_matrix(args.pheromones)
|
||||
with open(args.pheromones) as fd:
|
||||
phero = utils.load_matrix(fd)
|
||||
|
||||
else:
|
||||
LOGN( "Solve the TSP with an Ant Colony Algorithm" )
|
||||
|
||||
LOGN( "\tConvert the segment list into an adjacency list graph" )
|
||||
G = utils.adjacency_from_set( penrose_segments )
|
||||
G = graph.graph_of( penrose_segments )
|
||||
|
||||
LOGN( "\tCompute a tour" )
|
||||
max_it = 10
|
||||
|
|
@ -130,89 +134,68 @@ else:
|
|||
trajs.append(traj)
|
||||
|
||||
with open("d%i_tour.points" % depth, "w") as fd:
|
||||
for p in traj:
|
||||
fd.write("%f %f\n" % p)
|
||||
utils.write_points( traj, fd )
|
||||
|
||||
with open("d%i_pheromones.mat" % depth, "w") as fd:
|
||||
for row in phero:
|
||||
key = "%f,%f:" % row
|
||||
line = key
|
||||
for k in phero[row]:
|
||||
val = phero[row][k]
|
||||
line += "%f,%f=%f " % (k[0],k[1],val)
|
||||
fd.write( line + "\n" )
|
||||
utils.write_matrix( phero, fd )
|
||||
|
||||
|
||||
########################################################################
|
||||
# TRIANGULATION
|
||||
########################################################################
|
||||
|
||||
triangulated = []
|
||||
|
||||
if args.triangulation:
|
||||
triangulation_edges = utils.load_segments(args.triangulation)
|
||||
with open(args.triangulation) as fd:
|
||||
triangulated = triangulation.load(args.triangulation)
|
||||
|
||||
else:
|
||||
LOGN( "Compute the triangulation of the penrose vertices" )
|
||||
points = utils.vertices_of(penrose_segments)
|
||||
triangles = triangulation.delaunay_bowyer_watson( points, do_plot = False )
|
||||
|
||||
# LOGN( "\tCompute the convex hull of",len(points),"points" )
|
||||
# # Should convert the set into a list
|
||||
# hull = hull.convex_hull( list(points) )
|
||||
# hull_edges = list(utils.tour(hull))
|
||||
# LOGN( "\t\tHull of",len(hull_edges),"edges" )
|
||||
|
||||
LOGN( "\tRemove triangles that are not sub-parts of the Penrose tiling" )
|
||||
# def adjoin_hull(triangle):
|
||||
# """Return True if the given triangle has at least one edge that is in the set hull_edges."""
|
||||
# for (p,q) in utils.tour(list(triangle)):
|
||||
# if (p,q) in hull_edges or (q,p) in hull_edges:
|
||||
# return True
|
||||
# return False
|
||||
|
||||
def acute_triangle(triangle):
|
||||
"""Return True if the center of the circumcircle of the given triangle lies inside the triangle.
|
||||
That is if the triangle is acute."""
|
||||
return triangulation.in_triangle( triangulation.circumcircle(triangle)[0], triangle )
|
||||
|
||||
# FIXME at depth 3, some triangles have an edge in the convex hull...
|
||||
# Filter out edges that are in hull_edges
|
||||
# tri_nohull = list(filter_if_not( adjoin_hull, triangles ))
|
||||
# Filter out triangles that are obtuse
|
||||
# triangulated = list(filter_if_not( acute_triangle, tri_nohull ))
|
||||
|
||||
triangulated = list(filter_if_not( acute_triangle, triangles ))
|
||||
LOGN( "\t\tRemoved", len(triangles)-len(triangulated), "triangles" )
|
||||
|
||||
triangulation_edges = triangulation.edges_of( triangulated )
|
||||
with open("d%i_triangulation.segments" % depth, "w") as fd:
|
||||
for p0,p1 in triangulation_edges:
|
||||
fd.write("%f %f %f %f\n" % (p0[0],p0[1],p1[0],p1[1]) )
|
||||
with open("d%i_triangulation.triangles" % depth, "w") as fd:
|
||||
triangulation.write( triangulated, fd )
|
||||
|
||||
triangulation_edges = triangulation.edges_of( triangulated )
|
||||
|
||||
|
||||
########################################################################
|
||||
# VORONOÏ
|
||||
########################################################################
|
||||
|
||||
voronoi_graph = {}
|
||||
|
||||
if args.voronoi:
|
||||
voronoi_graph = utils.load_adjacency(args.voronoi)
|
||||
with open(args.voronoi) as fd:
|
||||
voronoi_graph = graph.load( fd )
|
||||
|
||||
else:
|
||||
# LOGN( "Compute the nodes of the Voronoï diagram" )
|
||||
voronoi_tri_graph = voronoi.dual(triangulated)
|
||||
voronoi_tri_edges = voronoi.edges_of( voronoi.dual(triangulated) )
|
||||
voronoi_tri_edges = graph.edges_of( voronoi.dual(triangulated) )
|
||||
voronoi_tri_centers = voronoi_tri_graph.keys()
|
||||
|
||||
voronoi_graph = voronoi.merge_enclosed( voronoi_tri_graph, penrose_segments )
|
||||
|
||||
with open("d%i_voronoi.graph" % depth, "w") as fd:
|
||||
for k in voronoi_graph:
|
||||
fd.write( "%f,%f:" % (x(k),y(k)) )
|
||||
for p in voronoi_graph[k]:
|
||||
fd.write( "%f,%f " % (x(p),y(p)) )
|
||||
fd.write("\n")
|
||||
graph.write( voronoi_graph, fd )
|
||||
|
||||
|
||||
voronoi_edges = voronoi.edges_of( voronoi_graph )
|
||||
voronoi_centers = voronoi_graph.keys()
|
||||
voronoi_edges = graph.edges_of( voronoi_graph )
|
||||
voronoi_centers = graph.nodes_of( voronoi_graph )
|
||||
|
||||
|
||||
########################################################################
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ import sys
|
|||
import math
|
||||
from itertools import ifilterfalse as filter_if_not
|
||||
|
||||
from utils import tour,LOG,LOGN,x,y
|
||||
from geometry import mid, middle
|
||||
from utils import tour,LOG,LOGN
|
||||
from geometry import mid,middle,x,y
|
||||
|
||||
# Based on http://paulbourke.net/papers/triangulate/
|
||||
# Efficient Triangulation Algorithm Suitable for Terrain Modelling
|
||||
|
|
@ -132,15 +132,6 @@ def bounds( vertices ):
|
|||
return (xmin,ymin),(xmax,ymax)
|
||||
|
||||
|
||||
def edges_of( triangulation ):
|
||||
"""Return a list containing the edges of the given list of 3-tuples of points"""
|
||||
edges = []
|
||||
for t in triangulation:
|
||||
for e in tour(list(t)):
|
||||
edges.append( e )
|
||||
return edges
|
||||
|
||||
|
||||
def supertriangle( vertices, delta = 0.1 ):
|
||||
"""Return a super-triangle that encloses all given points.
|
||||
The super-triangle has its base at the bottom and encloses the bounding box at a distance given by:
|
||||
|
|
@ -345,6 +336,37 @@ def delaunay_bowyer_watson( points, supertri = None, superdelta = 0.1, epsilon =
|
|||
return triangulation
|
||||
|
||||
|
||||
def edges_of( triangulation ):
|
||||
"""Return a list containing the edges of the given list of 3-tuples of points"""
|
||||
edges = []
|
||||
for t in triangulation:
|
||||
for e in tour(list(t)):
|
||||
edges.append( e )
|
||||
return edges
|
||||
|
||||
|
||||
def load( stream ):
|
||||
triangles = []
|
||||
for line in stream:
|
||||
if line.strip()[0] != "#":
|
||||
tri = line.split()
|
||||
assert(len(tri)==3)
|
||||
triangle = []
|
||||
for p in tri:
|
||||
assert(len(p)==2)
|
||||
point = [ (float(y),float(y)) for i,j in p.split(",")]
|
||||
triangle.append( point )
|
||||
triangles.append( triangle )
|
||||
return triangles
|
||||
|
||||
|
||||
def write( triangles, stream ):
|
||||
for tri in triangles:
|
||||
assert(len(tri)==3)
|
||||
p,q,r = tri
|
||||
stream.write("%f,%f %f,%f %f,%f\n" % ( x(p),y(p), x(q),y(q), x(r),y(r) ) )
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import random
|
||||
import utils
|
||||
|
|
|
|||
108
utils.py
108
utils.py
|
|
@ -17,80 +17,68 @@ def LOGN( *args ):
|
|||
LOG("\n")
|
||||
|
||||
|
||||
def load_points( filename ):
|
||||
def load_points( stream ):
|
||||
points = []
|
||||
with open(filename) as fd:
|
||||
for line in fd:
|
||||
if line.strip()[0] != "#":
|
||||
p = tuple([float(i) for i in line.split()])
|
||||
assert(len(p)==2)
|
||||
points.append( p )
|
||||
for line in stream:
|
||||
if line.strip()[0] != "#":
|
||||
p = tuple([float(i) for i in line.split()])
|
||||
assert(len(p)==2)
|
||||
points.append( p )
|
||||
return points
|
||||
|
||||
|
||||
def load_segments( filename ):
|
||||
def write_points( points, stream ):
|
||||
for p in points:
|
||||
stream.write( "%f,%f\n" % ( x(p),y(p) ) )
|
||||
|
||||
|
||||
def load_segments( stream ):
|
||||
segments = []
|
||||
with open(filename) as fd:
|
||||
for line in fd:
|
||||
if line.strip()[0] != "#":
|
||||
edge = [float(i) for i in line.split()]
|
||||
assert(len(edge)==4)
|
||||
segments.append( ((edge[0],edge[1]),(edge[2],edge[3])) )
|
||||
for line in stream:
|
||||
if line.strip()[0] != "#":
|
||||
seg = line.strip()
|
||||
assert(len(seg)==2)
|
||||
edge = []
|
||||
for p in seg:
|
||||
assert(len(p)==2)
|
||||
point = tuple([float(i) for i in seg])
|
||||
edge.append( point )
|
||||
segments.append( edge )
|
||||
return segments
|
||||
|
||||
|
||||
def load_triangles( filename ):
|
||||
triangles = []
|
||||
with open(filename) as fd:
|
||||
for line in fd:
|
||||
if line.strip()[0] != "#":
|
||||
tri = [float(i) for i in line.split()]
|
||||
assert(len(tri)==6)
|
||||
triangles.append( ((tri[0],tri[1]),(tri[2],tri[3]),(tri[4],tri[5])) )
|
||||
return triangles
|
||||
def write_segments( segments, stream ):
|
||||
for seg in segments:
|
||||
for p in seg:
|
||||
stream.write( "%f,%f " % ( x(p),y(p) ) )
|
||||
stream.write( "\n" )
|
||||
|
||||
|
||||
def load_matrix( filename ):
|
||||
def load_matrix( stream ):
|
||||
matrix = {}
|
||||
with open(filename) as fd:
|
||||
for line in fd:
|
||||
if line.strip()[0] != "#":
|
||||
skey,svals = line.split(":")
|
||||
key = tuple((float(i) for i in skey.split(',')))
|
||||
col = {}
|
||||
for stri in svals.split():
|
||||
sk,sv = stri.split("=")
|
||||
value = float(sv)
|
||||
k = tuple((float(i) for i in sk.split(",")))
|
||||
col[k] = value
|
||||
matrix[key] = col
|
||||
assert(len(matrix) == len(matrix[key]))
|
||||
for line in stream:
|
||||
if line.strip()[0] != "#":
|
||||
skey,svals = line.split(":")
|
||||
key = tuple((float(i) for i in skey.split(',')))
|
||||
col = {}
|
||||
for stri in svals.split():
|
||||
sk,sv = stri.split("=")
|
||||
value = float(sv)
|
||||
k = tuple((float(i) for i in sk.split(",")))
|
||||
col[k] = value
|
||||
matrix[key] = col
|
||||
assert(len(matrix) == len(matrix[key]))
|
||||
return matrix
|
||||
|
||||
|
||||
def load_adjacency( filename ):
|
||||
graph = {}
|
||||
with open(filename) as fd:
|
||||
for line in fd:
|
||||
if line.strip()[0] != "#":
|
||||
skey,svals = line.split(":")
|
||||
key = tuple((float(i) for i in skey.split(',')))
|
||||
graph[key] = []
|
||||
for sp in svals.split():
|
||||
p = tuple(float(i) for i in sp.split(","))
|
||||
assert(len(p)==2)
|
||||
graph[key].append( p )
|
||||
return graph
|
||||
|
||||
|
||||
def adjacency_from_set( segments ):
|
||||
graph = {}
|
||||
for start,end in segments:
|
||||
graph[start] = graph.get( start, [] )
|
||||
graph[start].append( end )
|
||||
graph[end] = graph.get( end, [] )
|
||||
graph[end].append( start )
|
||||
return graph
|
||||
def write_matrix( mat, stream):
|
||||
for row in mat:
|
||||
key = "%f,%f:" % row
|
||||
line = key
|
||||
for k in mat[row]:
|
||||
val = mat[row][k]
|
||||
line += "%f,%f=%f " % (k[0],k[1],val)
|
||||
stream.write( line + "\n" )
|
||||
|
||||
|
||||
def vertices_of( segments ):
|
||||
|
|
|
|||
14
voronoi.py
14
voronoi.py
|
|
@ -4,6 +4,7 @@
|
|||
from utils import tour,LOG,LOGN,x,y
|
||||
import triangulation
|
||||
import geometry
|
||||
import graph
|
||||
|
||||
def nodes( triangles ):
|
||||
"""Compute the locations of the centers of all the circumscribed circles of the given triangles"""
|
||||
|
|
@ -68,17 +69,6 @@ def dual( triangles ):
|
|||
return graph
|
||||
|
||||
|
||||
def edges_of( graph ):
|
||||
# edges = set()
|
||||
edges = []
|
||||
for k in graph:
|
||||
for n in graph[k]:
|
||||
if k != n and (k,n) not in edges and (n,k) not in edges:
|
||||
# edges.add( (k,n) )
|
||||
edges.append( (k,n) )
|
||||
return edges
|
||||
|
||||
|
||||
def merge_nodes( graph, n0, n1, n2 ):
|
||||
"""Merge n0 and n1 nodes as n2 within the given graph."""
|
||||
|
||||
|
|
@ -179,7 +169,7 @@ if __name__ == "__main__":
|
|||
delaunay_edges = triangulation.edges_of( triangles )
|
||||
|
||||
voronoi_graph = dual( triangles )
|
||||
voronoi_edges = edges_of( voronoi_graph )
|
||||
voronoi_edges = graph.edges_of( voronoi_graph )
|
||||
print voronoi_edges
|
||||
|
||||
ax = fig.add_subplot(111)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue