2011-09-09 36 views
3

我需要通过替换其中一个点来改变三角形。但是,我需要检测这样做是否会导致三角形翻转。检测改变点时三角形是否翻转

例如,由点限定的三角形:

[(1.0,1.0), (2.0,3.0), (3.0,1.0)] 

看起来像这样:

original triangle

如果我改变从(3.0,1.0)第三点到(1.0,2.0),它翻转,如如下所示:

flipped triangle

我已经写,可检测的三角形是通过计算对于所述固定点的方程和检测在所述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编写的事实并不重要。我会接受一个只是一个公式或描述得很好的技术的答案。

编辑:上意味着什么三角“翻转”

考虑下面的四个三角形的更多信息:

enter image description here

左上角的是原来的三角形。红线(全部相同)是两个固定点。三个三角形的其余部分取代了第三点。右上角和左下角的三角形不翻转,而右下角的三角形翻转。实质上,如果第三点结束于由两个固定点形成的虚线的相反侧,则该三角形被“翻转”。

UPDATE2:使用跨产品工作职能:

+2

我不认为你已经清楚地说明了你的意思是“翻转”:看起来你有一些规则使得一个点在每个三角形特别,但你没有明确说明这个规则是什么 –

+0

啊,我现在明白了,我再看看:三重点中每个点的位置定义了该点的身份。定义“翻转”,使得由这些点定义的(“有弹性的”!)物理三角形必须围绕包含三角形的2D平面中的轴在3D空间中旋转,以便从第一个三角形到第二。也许没有比你原来的解释更清楚! –

+0

我更新了一些关于翻转三角形意味着什么的更多信息。这是否更清楚? – jterrace

回答

8

计算你的三点产生的两个向量的cross-product。 如果叉积的方向改变了符号,三角形就会翻转。

例如:

鉴于[(1.0,1.0), (2.0,3.0), (3.0,1.0)]: 形式的两个(3D)向量

(2-1,3-1,0) = (1,2,0)(3-1,1-1,0) = (2,0,0)

取他们的叉积:

(1,2,0) x (2,0,0) = (0,0,0-4) = (0,0,-4) 

或者,使用numpy的:

import numpy as np 
np.cross([1,2,0],[2,0,0]) 
# array([ 0, 0, -4]) 

虽然给出[(1.0,1.0), (2.0,3.0), (1.0,2.0)]时:我们形成两个(3D)向量:

(2-1,3-1,0) = (1,2,0)(1-1,2-1,0) = (0,1,0)

并再次把他们的叉积:

np.cross([1,2,0],[0,1,0]) 
# array([0, 0, 1]) 

由于矢量(0, 0,-4)点“下”,矢量(0,0,1)指向“上”,三角形翻转。


你真的不需要numpy这个。如果你计算出纸上的数学结果,如果点是由(x1,y1),(x2,y2)和(x3,y3), 给出的,那么交叉乘积中的关键数字由

(y2-y1)*(x2-x1) - (y3-y1)*(x2-x1) 

你只需要计算该值并观察其符号的变化。 (当且仅当上面的表达式等于0时,这三点是共线的。)

+0

不应该(2,1,0)是(2,0,0)? – jterrace

+0

这有效。更新的问题与工作funciton。谢谢! – jterrace

+0

@jterrace:哎呀,你说得对。纠正... – unutbu

0

你可以用is_straight_line功能启动would_flip功能,和其余代码只有当它是不是一条直线执行。

+0

我可以检测到分母是0还是无穷大,然后根据输入的y值计算方程,但我希望更优雅的解决方案 – jterrace