#!/usr/bin/env python3 import sys # This script generates a configuration of 3-staircases in which there is a # grid of particles in one phase, and the rest of space is filled with # particles in another phase. # size of grid L1=100 L2=100 # grid of particles in phase 1 N11=12 N12=12 # position of lower left particle in phase 1 x01=30+N12 x02=30 # only print from here to there l11=16 l12=16 l21=80 l22=88 # R2 of the model R2=3 def main(): # particles in phase 1 particles1=[] # particles in phase 2 particles2=[] fill_particles1(particles1) fill_particles2(particles2,particles1) # join particles particles=particles1+particles2 # compute which particles have a Voronoi cells containing a given site voronoi_index=particles_in_voronoi(particles) # compute the Voronoi cells of each particle voronois=voronoi_of_particles(voronoi_index,particles) # check whether the particles are in the GFc GFc=particles_in_GFc(voronois,particles1,particles2) # boundary of GFc support=GFc_support(GFc,voronois) GFc_boundary=boundary(support) # print print_headers() print_particles(particles1,particles2,GFc) print_boundary(GFc_boundary) print_footers() # generate grid of particles in phase 1 def fill_particles1(particles1): for k1 in range(N11): for k2 in range(N12): particles1.append((x01+2*k1-k2,x02+k1+3*k2,1)) # fill the rest of space with particles in phase 2 def fill_particles2(particles2, particles1): for x1 in range(L1): for x2 in range(L2): # index of particle k1=(x1+3*x2)/7 k2=(2*x1-x2)/7 # check the indices are integers: if k1 != int(k1) or k2 != int(k2): continue # check overlap with particles in phase 1 if check_overlap_1((x1,x2),particles1): continue particles2.append((x1,x2,2)) # check overlap with particles in phase 1 def check_overlap_1(x,particles1): for p in particles1: if check_overlap(x,p): return True return False # check overlap between two 3-staircases def check_overlap(x,y): if max(abs(y[0]-x[0]),abs(y[1]-x[1]))>2: return False if abs((y[1]-x[1])+(y[0]-x[0]))<=2: return True return False # given a site, compute the particles whose Voronoi cell the site is in def particles_in_voronoi(particles): out=[] for x1 in range(L1): for x2 in range(L2): # minimize distance mindist=L1+L2+1 candidate_list=[] for p in particles: dd=dist_support((x1,x2),p) if dd=p[0] and x[1]>=p[1]: return 0 # base out=abs(x[0]-p[0])+abs(x[1]-p[1]) # correct this depending on which site in \sigma_p is actually closest # lower left quadrant: p is the closest if x[0]-p[0]<=0 and x[1]-p[1]<=0: return out # lines next to lower left quadrant: neighbor of p closest if x[0]-p[0]==1 and x[1]-p[1]<=0 or x[1]-p[1]==1 and x[0]-p[0]<=0: return out-1 # otherwise: second neightbor of p closest return out-2 # from a table associating sites to voronoi cells, get particles def voronoi_of_particles(voronoi_index,particles): out=[] # output is indexed in the same order as particles for p in particles: vois=[] for v in voronoi_index: if p in v[1]: vois.append(v[0]) out.append((p,vois)) return out # find which particles are in the GFc def particles_in_GFc(voronois,particles1,particles2): out=[] # loop over particles for v in voronois: # check all other particles for w in voronois: # skip v if v==w: continue # check whether the distance between the cells is <=R2 if set_dist(v[1],w[1])>R2: continue # check whether w is #-correct if not ((w[0][2]==1 and sharp_correct1(w[0],particles1)) or (w[0][2]==2 and sharp_correct2(w[0],particles2))): # in GFc out.append(v[0]) break return out # distance between two sets def set_dist(s1,s2): if len(s1)==0 or len(s2)==0: print("error: computing the distance between two sets, one of which is empty",file=sys.stderr) exit(-1) return -1 mind=abs(s1[0][0]-s2[0][0])+abs(s1[0][1]-s2[0][1]) for x in s1: for y in s2: if abs(x[0]-y[0])+abs(x[1]-y[1])=l11 and p[0]<=l21 and p[1]>=l12 and p[1]<=l22: if p in GFc: print(r'\staircase{green}{('+str(p[0])+','+str(p[1])+')}') else: print(r'\staircase{cyan}{('+str(p[0])+','+str(p[1])+')}') for p in particles2: if p[0]>=l11 and p[0]<=l21 and p[1]>=l12 and p[1]<=l22: if p in GFc: print(r'\staircase{yellow}{('+str(p[0])+','+str(p[1])+')}') else: print(r'\staircase{red}{('+str(p[0])+','+str(p[1])+')}') def print_boundary(boundary): for seg in boundary: if seg[0][0]>=l11 and seg[0][0]<=l21 and seg[0][1]>=l12 and seg[0][1]<=l22: if seg[1][0]>=l11 and seg[1][0]<=l21 and seg[1][1]>=l12 and seg[1][1]<=l22: print(r'\draw[line width=8pt]('+str(seg[0][0])+','+str(seg[0][1])+')--('+str(seg[1][0])+','+str(seg[1][1])+');') def print_footers(): print(r''' \end{tikzpicture} \end{document}''') main()