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 lindenmayer
|
||||||
import triangulation
|
import triangulation
|
||||||
import voronoi
|
import voronoi
|
||||||
|
import graph
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
|
|
||||||
|
|
@ -53,7 +54,8 @@ penrose_segments = set()
|
||||||
|
|
||||||
if args.penrose:
|
if args.penrose:
|
||||||
LOGN( "Load the penrose tiling" )
|
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:
|
else:
|
||||||
LOGN( "Draw the penrose tiling" )
|
LOGN( "Draw the penrose tiling" )
|
||||||
|
|
@ -79,11 +81,11 @@ else:
|
||||||
penrose.draw( depth )
|
penrose.draw( depth )
|
||||||
|
|
||||||
# save this intermediate step
|
# 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
|
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]:
|
if args.tour != [None]:
|
||||||
for tour in args.tour:
|
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.notsp:
|
||||||
if args.tour == [None] or not args.pheromones:
|
if args.tour == [None] or not args.pheromones:
|
||||||
|
|
@ -102,13 +105,14 @@ if args.notsp:
|
||||||
sys.exit(error_codes["NO-TSP"])
|
sys.exit(error_codes["NO-TSP"])
|
||||||
|
|
||||||
if args.pheromones:
|
if args.pheromones:
|
||||||
phero = utils.load_matrix(args.pheromones)
|
with open(args.pheromones) as fd:
|
||||||
|
phero = utils.load_matrix(fd)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
LOGN( "Solve the TSP with an Ant Colony Algorithm" )
|
LOGN( "Solve the TSP with an Ant Colony Algorithm" )
|
||||||
|
|
||||||
LOGN( "\tConvert the segment list into an adjacency list graph" )
|
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" )
|
LOGN( "\tCompute a tour" )
|
||||||
max_it = 10
|
max_it = 10
|
||||||
|
|
@ -130,89 +134,68 @@ else:
|
||||||
trajs.append(traj)
|
trajs.append(traj)
|
||||||
|
|
||||||
with open("d%i_tour.points" % depth, "w") as fd:
|
with open("d%i_tour.points" % depth, "w") as fd:
|
||||||
for p in traj:
|
utils.write_points( traj, fd )
|
||||||
fd.write("%f %f\n" % p)
|
|
||||||
with open("d%i_pheromones.mat" % depth, "w") as fd:
|
with open("d%i_pheromones.mat" % depth, "w") as fd:
|
||||||
for row in phero:
|
utils.write_matrix( phero, fd )
|
||||||
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" )
|
|
||||||
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# TRIANGULATION
|
# TRIANGULATION
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
|
triangulated = []
|
||||||
|
|
||||||
if args.triangulation:
|
if args.triangulation:
|
||||||
triangulation_edges = utils.load_segments(args.triangulation)
|
with open(args.triangulation) as fd:
|
||||||
|
triangulated = triangulation.load(args.triangulation)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
LOGN( "Compute the triangulation of the penrose vertices" )
|
LOGN( "Compute the triangulation of the penrose vertices" )
|
||||||
points = utils.vertices_of(penrose_segments)
|
points = utils.vertices_of(penrose_segments)
|
||||||
triangles = triangulation.delaunay_bowyer_watson( points, do_plot = False )
|
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" )
|
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):
|
def acute_triangle(triangle):
|
||||||
"""Return True if the center of the circumcircle of the given triangle lies inside the triangle.
|
"""Return True if the center of the circumcircle of the given triangle lies inside the triangle.
|
||||||
That is if the triangle is acute."""
|
That is if the triangle is acute."""
|
||||||
return triangulation.in_triangle( triangulation.circumcircle(triangle)[0], triangle )
|
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
|
# Filter out triangles that are obtuse
|
||||||
# triangulated = list(filter_if_not( acute_triangle, tri_nohull ))
|
|
||||||
|
|
||||||
triangulated = list(filter_if_not( acute_triangle, triangles ))
|
triangulated = list(filter_if_not( acute_triangle, triangles ))
|
||||||
LOGN( "\t\tRemoved", len(triangles)-len(triangulated), "triangles" )
|
LOGN( "\t\tRemoved", len(triangles)-len(triangulated), "triangles" )
|
||||||
|
|
||||||
triangulation_edges = triangulation.edges_of( triangulated )
|
with open("d%i_triangulation.triangles" % depth, "w") as fd:
|
||||||
with open("d%i_triangulation.segments" % depth, "w") as fd:
|
triangulation.write( triangulated, fd )
|
||||||
for p0,p1 in triangulation_edges:
|
|
||||||
fd.write("%f %f %f %f\n" % (p0[0],p0[1],p1[0],p1[1]) )
|
triangulation_edges = triangulation.edges_of( triangulated )
|
||||||
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# VORONOÏ
|
# VORONOÏ
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
|
voronoi_graph = {}
|
||||||
|
|
||||||
if args.voronoi:
|
if args.voronoi:
|
||||||
voronoi_graph = utils.load_adjacency(args.voronoi)
|
with open(args.voronoi) as fd:
|
||||||
|
voronoi_graph = graph.load( fd )
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# LOGN( "Compute the nodes of the Voronoï diagram" )
|
# LOGN( "Compute the nodes of the Voronoï diagram" )
|
||||||
voronoi_tri_graph = voronoi.dual(triangulated)
|
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_tri_centers = voronoi_tri_graph.keys()
|
||||||
|
|
||||||
voronoi_graph = voronoi.merge_enclosed( voronoi_tri_graph, penrose_segments )
|
voronoi_graph = voronoi.merge_enclosed( voronoi_tri_graph, penrose_segments )
|
||||||
|
|
||||||
with open("d%i_voronoi.graph" % depth, "w") as fd:
|
with open("d%i_voronoi.graph" % depth, "w") as fd:
|
||||||
for k in voronoi_graph:
|
graph.write( voronoi_graph, fd )
|
||||||
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")
|
|
||||||
|
|
||||||
|
|
||||||
voronoi_edges = voronoi.edges_of( voronoi_graph )
|
voronoi_edges = graph.edges_of( voronoi_graph )
|
||||||
voronoi_centers = voronoi_graph.keys()
|
voronoi_centers = graph.nodes_of( voronoi_graph )
|
||||||
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ import sys
|
||||||
import math
|
import math
|
||||||
from itertools import ifilterfalse as filter_if_not
|
from itertools import ifilterfalse as filter_if_not
|
||||||
|
|
||||||
from utils import tour,LOG,LOGN,x,y
|
from utils import tour,LOG,LOGN
|
||||||
from geometry import mid, middle
|
from geometry import mid,middle,x,y
|
||||||
|
|
||||||
# Based on http://paulbourke.net/papers/triangulate/
|
# Based on http://paulbourke.net/papers/triangulate/
|
||||||
# Efficient Triangulation Algorithm Suitable for Terrain Modelling
|
# Efficient Triangulation Algorithm Suitable for Terrain Modelling
|
||||||
|
|
@ -132,15 +132,6 @@ def bounds( vertices ):
|
||||||
return (xmin,ymin),(xmax,ymax)
|
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 ):
|
def supertriangle( vertices, delta = 0.1 ):
|
||||||
"""Return a super-triangle that encloses all given points.
|
"""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:
|
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
|
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__":
|
if __name__ == "__main__":
|
||||||
import random
|
import random
|
||||||
import utils
|
import utils
|
||||||
|
|
|
||||||
108
utils.py
108
utils.py
|
|
@ -17,80 +17,68 @@ def LOGN( *args ):
|
||||||
LOG("\n")
|
LOG("\n")
|
||||||
|
|
||||||
|
|
||||||
def load_points( filename ):
|
def load_points( stream ):
|
||||||
points = []
|
points = []
|
||||||
with open(filename) as fd:
|
for line in stream:
|
||||||
for line in fd:
|
if line.strip()[0] != "#":
|
||||||
if line.strip()[0] != "#":
|
p = tuple([float(i) for i in line.split()])
|
||||||
p = tuple([float(i) for i in line.split()])
|
assert(len(p)==2)
|
||||||
assert(len(p)==2)
|
points.append( p )
|
||||||
points.append( p )
|
|
||||||
return points
|
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 = []
|
segments = []
|
||||||
with open(filename) as fd:
|
for line in stream:
|
||||||
for line in fd:
|
if line.strip()[0] != "#":
|
||||||
if line.strip()[0] != "#":
|
seg = line.strip()
|
||||||
edge = [float(i) for i in line.split()]
|
assert(len(seg)==2)
|
||||||
assert(len(edge)==4)
|
edge = []
|
||||||
segments.append( ((edge[0],edge[1]),(edge[2],edge[3])) )
|
for p in seg:
|
||||||
|
assert(len(p)==2)
|
||||||
|
point = tuple([float(i) for i in seg])
|
||||||
|
edge.append( point )
|
||||||
|
segments.append( edge )
|
||||||
return segments
|
return segments
|
||||||
|
|
||||||
|
|
||||||
def load_triangles( filename ):
|
def write_segments( segments, stream ):
|
||||||
triangles = []
|
for seg in segments:
|
||||||
with open(filename) as fd:
|
for p in seg:
|
||||||
for line in fd:
|
stream.write( "%f,%f " % ( x(p),y(p) ) )
|
||||||
if line.strip()[0] != "#":
|
stream.write( "\n" )
|
||||||
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 load_matrix( filename ):
|
def load_matrix( stream ):
|
||||||
matrix = {}
|
matrix = {}
|
||||||
with open(filename) as fd:
|
for line in stream:
|
||||||
for line in fd:
|
if line.strip()[0] != "#":
|
||||||
if line.strip()[0] != "#":
|
skey,svals = line.split(":")
|
||||||
skey,svals = line.split(":")
|
key = tuple((float(i) for i in skey.split(',')))
|
||||||
key = tuple((float(i) for i in skey.split(',')))
|
col = {}
|
||||||
col = {}
|
for stri in svals.split():
|
||||||
for stri in svals.split():
|
sk,sv = stri.split("=")
|
||||||
sk,sv = stri.split("=")
|
value = float(sv)
|
||||||
value = float(sv)
|
k = tuple((float(i) for i in sk.split(",")))
|
||||||
k = tuple((float(i) for i in sk.split(",")))
|
col[k] = value
|
||||||
col[k] = value
|
matrix[key] = col
|
||||||
matrix[key] = col
|
assert(len(matrix) == len(matrix[key]))
|
||||||
assert(len(matrix) == len(matrix[key]))
|
|
||||||
return matrix
|
return matrix
|
||||||
|
|
||||||
|
|
||||||
def load_adjacency( filename ):
|
def write_matrix( mat, stream):
|
||||||
graph = {}
|
for row in mat:
|
||||||
with open(filename) as fd:
|
key = "%f,%f:" % row
|
||||||
for line in fd:
|
line = key
|
||||||
if line.strip()[0] != "#":
|
for k in mat[row]:
|
||||||
skey,svals = line.split(":")
|
val = mat[row][k]
|
||||||
key = tuple((float(i) for i in skey.split(',')))
|
line += "%f,%f=%f " % (k[0],k[1],val)
|
||||||
graph[key] = []
|
stream.write( line + "\n" )
|
||||||
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 vertices_of( segments ):
|
def vertices_of( segments ):
|
||||||
|
|
|
||||||
14
voronoi.py
14
voronoi.py
|
|
@ -4,6 +4,7 @@
|
||||||
from utils import tour,LOG,LOGN,x,y
|
from utils import tour,LOG,LOGN,x,y
|
||||||
import triangulation
|
import triangulation
|
||||||
import geometry
|
import geometry
|
||||||
|
import graph
|
||||||
|
|
||||||
def nodes( triangles ):
|
def nodes( triangles ):
|
||||||
"""Compute the locations of the centers of all the circumscribed circles of the given 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
|
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 ):
|
def merge_nodes( graph, n0, n1, n2 ):
|
||||||
"""Merge n0 and n1 nodes as n2 within the given graph."""
|
"""Merge n0 and n1 nodes as n2 within the given graph."""
|
||||||
|
|
||||||
|
|
@ -179,7 +169,7 @@ if __name__ == "__main__":
|
||||||
delaunay_edges = triangulation.edges_of( triangles )
|
delaunay_edges = triangulation.edges_of( triangles )
|
||||||
|
|
||||||
voronoi_graph = dual( triangles )
|
voronoi_graph = dual( triangles )
|
||||||
voronoi_edges = edges_of( voronoi_graph )
|
voronoi_edges = graph.edges_of( voronoi_graph )
|
||||||
print voronoi_edges
|
print voronoi_edges
|
||||||
|
|
||||||
ax = fig.add_subplot(111)
|
ax = fig.add_subplot(111)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue