我在2D平面中有一组对象(三角形),我想用一条线将它们分成两组大小相同的。
因为通常线会与某些三角形相交,所以我得到三组。一个在左侧,一个在右侧,一个与线路碰撞。
我现在想找个好行。我想出了一个成本函数:
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)))
我想用一些有效的算法替换优化器部分。我想,计算机图形专家可能会使用类似的东西。
提前致谢!