在2D空间中用线分隔三角形

时间:2018-03-21 22:49:04

标签: python algorithm graphics

我在2D平面中有一组对象(三角形),我想用一条线将它们分成两组大小相同的。

Perfect separation line

因为通常线会与某些三角形相交,所以我得到三组。一个在左侧,一个在右侧,一个与线路碰撞。

我现在想找个好行。我想出了一个成本函数:

cost=-min(len(set_left), len(set_right))

不幸的是,我想不出一个很好的算法来解决这个问题。 我写了一个python exaple来显示我的问题: (我使用x的实部和y坐标的虚部)

import scipy.optimize
import numpy as np

def scalar_prod (v1, v2):
    return v1.real*v2.real + v1.imag*v2.imag

def intersect_line_triangle (line, triangle):
    point = line[0]
    dir_ = line[1]
    # calculate normal vector
    n_vec = 1j * dir_
    # Calculate signed distance of each point
    dist = tuple(scalar_prod(n_vec, p-point) for p in triangle)
    if all(d > 0 for d in dist):
        return 1 # right
    if all(d < 0 for d in dist):
        return -1 # left
    return 0 # intersecting

def split_triangles_by_line (triangles, line):
    out = {-1: [], 0:[], 1:[]}
    for tri in triangles:
        out[intersect_line_triangle(line,tri)].append(tri)
    return out

def calc_cost (triangles, line):
    split = split_triangles_by_line(triangles, line)
    cost = -(min(len(split[-1]), len(split[1])))
    return cost

def calc_line (triangles, method='Powell'):
    # TODO: think about a good algorithm!
    center_point = sum(sum(tri) for tri in triangles) / (len(triangles)*3)
    init_point = center_point
    fun = lambda args: calc_cost(triangles, (args[0] + 1j* args[1], np.exp(1j*args[2])))
    res = scipy.optimize.minimize(fun,  [init_point.real, init_point.imag, np.pi/2], method=method)
    res_line = (res.x[0]+ 1j*res.x[1], np.exp(1j*res.x[2]))
    return res_line

triangles = [(0, 3j, 2), (4, 2+2j, 6+2j),
        (4j, 3+4j, 3+7j), (4+3j, 5+3j, 4+10j),
        (-1+5j, -1+8j, 3+9j)]
line = calc_line(triangles)
sep_triangles = split_triangles_by_line(triangles, line)
print("The resulting line is {} + {} * t".format(line[0], line[1]))
print("The triangles are separated:\nleft: {}\nright: {}\nintersected: {}".format(sep_triangles[-1], sep_triangles[1], sep_triangles[0]))
print("The cost is {}".format(calc_cost(triangles, line)))

我想用一些有效的算法替换优化器部分。我想,计算机图形专家可能会使用类似的东西。

提前致谢!

0 个答案:

没有答案