我想實現Newell的方法來根據here中的以下僞代碼計算Python中的曲面法線向量。使用Newell的方法計算Python中的曲面法線
Begin Function CalculateSurfaceNormal (Input Polygon) Returns Vector
Set Vertex Normal to (0, 0, 0)
Begin Cycle for Index in [0, Polygon.vertexNumber)
Set Vertex Current to Polygon.verts[Index]
Set Vertex Next to Polygon.verts[(Index plus 1) mod Polygon.vertexNumber]
Set Normal.x to Sum of Normal.x and (multiply (Current.y minus Next.y) by (Current.z plus Next.z))
Set Normal.y to Sum of Normal.y and (multiply (Current.z minus Next.z) by (Current.x plus Next.x))
Set Normal.z to Sum of Normal.z and (multiply (Current.x minus Next.x) by (Current.y plus Next.y))
End Cycle
Returning Normalize(Normal)
End Function
這裏是我的代碼:
Point3D = collections.namedtuple('Point3D', 'x y z')
def surface_normal(poly):
n = [0.0, 0.0, 0.0]
for i, v_curr in enumerate(poly):
v_next = poly[(i+1) % len(poly)]
n[0] += (v_curr.y - v_next.y) * (v_curr.z - v_next.z)
n[1] += (v_curr.z - v_next.z) * (v_curr.x - v_next.x)
n[2] += (v_curr.x - v_next.x) * (v_curr.y - v_next.y)
normalised = [i/sum(n) for i in n]
return normalised
def test_surface_normal():
poly = [Point3D(0.0, 0.0, 0.0),
Point3D(0.0, 1.0, 0.0),
Point3D(1.0, 1.0, 0.0),
Point3D(1.0, 0.0, 0.0)]
assert surface_normal(poly) == [0.0, 0.0, 1.0]
這未能在標準化步驟,因爲n
在這一點上是[0.0, 0.0, 0.0]
。如果我理解正確,應該是[0.0, 0.0, 1.0]
(Wolfram Alpha的confirmed)。
我在這裏做錯了什麼?有沒有更好的方法來計算python中的曲面法線?我的多邊形總是平面的,所以如果還有其他方法,Newell方法不是絕對必要的。
是的,我得到零除 - 因爲我試圖規範'[0,0,0]'這是不是一個有效的向量。這不應該是代碼中當時的價值。平面上,我的意思是第一個。 3D空間中的2D多邊形。 –
好吧,我也得到了這個(我通過使用這個來避免它 - 「normalised = [i/sum(n)if sum(n)!= 0.0 else 0 for i in n]' - 只能通過它) 。你的多邊形是否總是凸起的,還是有可能不是? – dblclik
它們可以是任何形狀,但不能自相交。而你的解決方法可能會失敗,例如使用矢量'[-0.5,0.0,0.5]'。我正在使用'try:except:'塊,但如果算法運行正常,則不需要。 –