예제 #1
0
    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