def cost(x): g_mod=modified_node_grid(g,n,x) # This one sucked: if 0: cost=np.sum([link_cost(g_mod,j) for j in links]) # mimic report_orthogonality() cost=0 if 1: nsi=4 # quads only right now... centers=g_mod.cells_center(mode='sequential') # this is somehow making the mean and max circumcenter error larger! offsets = g_mod.nodes['x'][g_mod.cells['nodes'][cells,:nsi]] - centers[cells,None,:] dists = utils.mag(offsets) # maybe lets small cells take over too much # cost += np.mean( np.std(dists,axis=1) / np.mean(dists,axis=1) ) # different, but not much better # cost += np.mean( np.std(dists,axis=1) ) base_cost=np.max( np.std(dists,axis=1) ) if verbose: print " Circum. cost: %f"%(base_cost) cost += base_cost if w_area>0 and len(links): # this helps a bit, but sometimes getting good areas # means distorting the shapes A=g_mod.cells_area() pairs=A[ g.edges['cells'][links] ] diffs=(pairs[:,0]-pairs[:,1])/pairs.mean(axis=1) area_cost=w_area*np.sum(diffs**2) if verbose: print " Area cost: %f"%area_cost cost+=area_cost if w_length>0: # if it's not too far off, this makes it look nicer at # the expense of circ. errors l_cost=0 g_mod.update_cell_edges() lengths=g_mod.edges_length() for c in cells: e=g_mod.cell_to_edges(c) if 0: # maybe that's too much leeway, and # the user should have to specify aspect ratios if len(e)==4: a,b,c,d=lengths[e] l_cost+=( ((a-c)/(a+c))**2 + ((b-d)/(b+d))**2 ) else: lmean=lengths.mean() l_cost+= np.sum( (lengths-lmean)**2 ) if verbose: print " Length cost: %f"%( w_length*l_cost ) cost+=w_length*l_cost if w_angle>0: # interior angle of cells deltas=np.diff(g_mod.nodes['x'][triples],axis=1) angles=np.diff( np.arctan2( deltas[:,:,1], deltas[:,:,0] ),axis=1) % (2*np.pi) * 180/np.pi angle_cost=w_angle*np.sum( (angles-90)**2 ) if verbose: print " Angle cost: %f"%angle_cost cost+=angle_cost if w_cangle>0: cangle_cost=0 for c in cells: nodes=g.cell_to_nodes(c) deltas=g_mod.nodes['x'][nodes] - g_mod.cells_center()[c] angles=np.arctan2(deltas[:,1],deltas[:,0]) * 180/np.pi cds=utils.cdiff(angles) % 360. cangle_cost+=np.sum( (cds-90)**4 ) if verbose: print " CAngle cost: %f"%( w_cangle*cangle_cost ) cost+=w_cangle*cangle_cost return cost