我有兩個段 AB和CD(紅色)。這兩個部分面對彼此。它們並不完全平行,但永遠不會彼此垂直。從這個角度來看,我需要找到這兩部分(藍色)中相互對立的兩個法線(即兩個法線在ABCD之外)的兩個法線(如何找到兩個相反的法線或兩個線段?
)。我知道如何計算線段的法線,但顯然每個線段都有兩個法線,我無法弄清楚如何以編程方式選擇我需要的線段。任何建議?
我有兩個段 AB和CD(紅色)。這兩個部分面對彼此。它們並不完全平行,但永遠不會彼此垂直。從這個角度來看,我需要找到這兩部分(藍色)中相互對立的兩個法線(即兩個法線在ABCD之外)的兩個法線(如何找到兩個相反的法線或兩個線段?
)。我知道如何計算線段的法線,但顯然每個線段都有兩個法線,我無法弄清楚如何以編程方式選擇我需要的線段。任何建議?
計算兩個段的中點之間的向量v,指向遠離AB到CD。現在,所需的法線到AB的投影必須是負的,並且所需的CD法線到v上的投影必須是正的。因此,只需計算法線,對v進行檢查,並根據需要否定法線以使其滿足條件。
這是用Python:
# use complex numbers to define minimal 2d vector datatype
def vec2d(x,y): return complex(x,y)
def rot90(v): return 1j * v
def inner_prod(u, v): return (u * v.conjugate()).real
def outward_normals(a, b, c, d):
n1 = rot90(b - a)
n2 = rot90(d - c)
mid = (c + d - a - b)/2
if inner_prod(n1, mid) > 0:
n1 = -n1
if inner_prod(n2, mid) < 0:
n2 = -n2
return n1, n2
請注意,我假設端點定義滿足於問題的條件的線路。當線條具有相同的中點時,也不檢查邊緣情況;在這種情況下,「外部」的概念不適用。
我不認爲這將始終有效(儘管它適用於所有繪製的案例)。在一個段的端點位於另一個段的相對側的情況下,中點實際上可能位於「錯誤」的一側... –
@Darren有趣的點,我假定不相交。但我還沒有設法爲我提出的方法構建一個反例,但只是在某些情況下,正確的選擇不清楚。如果你有一個特定的案例,這將有助於如果你要提供端點。 –
嘗試'行1 =(0,0) - >(1,0.25)'和'行2 =(1.25,-0.25) - >(2,2)'。如果我正確理解你的方法,我認爲這會給第1行錯誤的正常。 –
如下您可以減少爲標誌的四種組合:
計算法線的點積,負號表示,無論顯示外部或內部。
因爲我認爲你的法線具有單位長度,所以如果點積具有一個量級,則可以檢測到並行性。正值表示兩者顯示方向相同,負值表示兩者顯示方向不同。
它的法線不平行:參數化行爲x(t) = x0 + t * n
爲正常的n
並且計算兩者相交的t
。負數t
將表明兩者都顯示在外面。在步驟1中將組合從4減少到2就足夠了。
如果兩個法線都是parralel:計算法線到達的中點之間的時間爲t
您的細分。由於在第2是不夠的,如果你這樣做了法線的一個,當你從4步減少你的組合,以2 1
我認爲有兩種情況考慮:
情況1:線之間的交點發生在任一段的端點之外。
在這種情況下@Michael J. Barber建議的中點方法肯定會奏效。因此,在片段中點之間形成一個矢量,用這個中點矢量計算法線矢量的點積並檢查符號。
如果計算lineA
的正常值,則法線與矢量midB -> midA
的點積應該是+ve
。
案例2:行之間的交點出現在一個段的端點內。
在這種情況下,在其中一個端點之間形成一個向量,其中不包括包圍交點和交點本身。
做的段正常的點積包圍交點,這個新的向量應該是+ve
。
您可以通過要求兩個法線之間的點積爲-ve
(在垂直線段的情況下這只是不明確的)來找到另一個線段的向外法線。
我假定這些段不共線或實際相交。
希望這會有所幫助。
當段形成一個鈍角時,你想要做什麼?因此,「外部」和「反對」是不一樣的。 –
@Michael J.Barber,它不會發生,因爲線段之間的角度始終<90°。 –