2016-08-15
指定した面積になるように 座標を計算する。
def trans_area(pp, po, target, niter=30, ratio=0.1): """ Calculate positions which area close to a target. pp: list of x,y po: list of polygon(indexes) target: list of target area niter: number of iteration ratio: ratio of change """ pp = np.array(pp, dtype=float) for h in range(niter): for i in range(len(po)): a = area(pp, po[i]) r = 1 + (target[i]-a)/target[i]*ratio for j in po[i]: pp[j] *= r return pp def area(pp, pl): from more_itertools import pairwise return abs(sum((pp[i][0]-pp[j][0]) * (pp[i][1]+pp[j][1]) for i, j in pairwise(list(pl) + [pl[0)))/2 def view(pp, po): from IPython.display import SVG cols = 'red fuchsia purple navy blue teal aqua green lime olive yellow orange orangered maroon'.split() pp = np.array(pp) pp[:, 1] *= -1 mx, mn = pp.max(0), pp.min(0) pp = (pp - mn) / (mx-mn) s = ''.join(['<path fill="%s" d="%s"/>'%(cols[i%len(cols)], 'M'+' '.join(['L%g,%g'%(pp[j][0], pp[j][1]) for j in p])[1:]+' Z') for i, p in enumerate(po)]) return SVG('<svg viewBox="0 0 8 1">%s</svg>'% s) tgt = [2,0.8,1] pp = [(-1,0), (1,0), (-1,1), (0,1), (1,1), (-1,2), (0,2), (1,2)] po = [(0,1,4,3,2), (2,3,6,5), (3,4,7,6)] view(trans_area(pp, po, tgt), po)