我需要更改一个三角形,通过替换其中一个点来实现。但是,我需要检测这样做是否会导致三角形翻转。
例如,由以下点定义的三角形:
[(1.0,1.0), (2.0,3.0), (3.0,1.0)]
会是这个样子:
如果我将第三个点从 (3.0,1.0)
更改为 (1.0,2.0)
, 它就会翻转,如下所示:
我编写了一个计算静态点方程并检测 y 截距符号差异来检测三角形是否翻转的函数:
def would_flip(stationary, orig_third_point, candidate_third_point):
#m = (y2-y1)/(x2-x1)
slope = (stationary[1][3] - stationary[0][4]) / (stationary[1][0] - stationary[0][0])
#y = mx + b
#b = y-mx
yint = stationary[0][5] - slope * stationary[0][0]
orig_atline = slope * orig_third_point[0] + yint
candidate_atline = slope * candidate_third_point[0] + yint
if orig_atline > orig_third_point[1] and not(candidate_atline > candidate_third_point[1]) or \
orig_atline < orig_third_point[1] and not(candidate_atline < candidate_third_point[1]):
return True
return False
这对大多数情况都有效:
>>> would_flip([(1.0,1.0), (2.0,3.0)], (3.0,1.0), (1.0,2.0))
True
>>> would_flip([(1.0,1.0), (2.0,3.0)], (3.0,1.0), (4.0,2.0))
False
我遇到的问题是,如果静止点是垂直的,那么斜率就是无限大。
>>> would_flip([(1.0,1.0), (1.0,3.0)], (3.0,1.0), (4.0,2.0))
ZeroDivisionError: float division by zero
有没有更好/更快的方法来检测三角形翻转,使其对静止点是一条垂直线具有鲁棒性?它是用Python编写的并不重要。我会接受只有公式或者描述良好的技术的答案。
编辑:关于三角形“翻转”的更多信息
考虑下面的四个三角形:
上左是原始三角形。红线(全部相同)是两个静止点。其余的三角形替换第三个点。上右和下左的三角形没有翻转,而右下角的三角形翻转了。本质上,如果第三个点最终在由两个静态点形成的虚线的对面,则三角形会“翻转”。
更新2:使用叉积的工作函数:
def would_flip2(stationary, orig_third_point, candidate_third_point):
vec1 = numpy.array([stationary[1][0] - stationary[0][0], stationary[1][1] - stationary[0][1], 0])
vec2_orig = numpy.array([orig_third_point[0] - stationary[0][0], orig_third_point[1] - stationary[0][1], 0])
vec2_candidate = numpy.array([candidate_third_point[0] - stationary[0][0], candidate_third_point[1] - stationary[0][1], 0])
orig_direction = numpy.cross(vec1, vec2_orig)[2]
candidate_direction = numpy.cross(vec1, vec2_candidate)[2]
if orig_direction > 0 and not(candidate_direction > 0) or \
orig_direction < 0 and not(candidate_direction < 0):
return True
return False