2012-04-12 93 views
2

在3D網格中檢測無效三角形的最快方法是什麼?作爲無效我的意思是:無效三角形

  • 面積爲零
  • 三點共線點
  • 兩個重疊點

我們目前使用的這一點 - 很慢 - 做法:

if (Area(p1,p2,p3) < 1e-3) 

     Debug.WriteLine("Invalid triangle found!"); 

    public double Area(Point p1, Point p2, Point p3) 
    { 

     double[,] m = new double[3, 3]; 

     m[0, 0] = p1.Y; m[0, 1] = p1.Z; m[0, 2] = 1; 
     m[1, 0] = p2.Y; m[1, 1] = p2.Z; m[1, 2] = 1; 
     m[2, 0] = p3.Y; m[2, 1] = p3.Z; m[2, 2] = 1; 

     double det1 = Matrix.Determinant3(m); 

     m[0, 0] = p1.Z; m[0, 1] = p1.X; m[0, 2] = 1; 
     m[1, 0] = p2.Z; m[1, 1] = p2.X; m[1, 2] = 1; 
     m[2, 0] = p3.Z; m[2, 1] = p3.X; m[2, 2] = 1; 

     double det2 = Matrix.Determinant3(m); 

     m[0, 0] = p1.X; m[0, 1] = p1.Y; m[0, 2] = 1; 
     m[1, 0] = p2.X; m[1, 1] = p2.Y; m[1, 2] = 1; 
     m[2, 0] = p3.X; m[2, 1] = p3.Y; m[2, 2] = 1; 

     double det3 = Matrix.Determinant3(m); 

     return Math.Sqrt(det1 * det1 + det2 * det2 + det3 * det3)/2; 


    } 

感謝。

+0

零點區域應該來自共線點或重疊點(如您所述)。那麼爲什麼不檢查這兩個條件呢?我估計便宜得多。 – 2012-04-12 14:52:27

回答

0

零點區域的唯一方法是點是否都是共線。

嘗試類似如下:

p1_p2_slope = (p2.y - p1.y)/(p2.x - p1.x); 
p2_p3_slope = (p3.y - p2.y)/(p3.x - p2.x); 
if(p1_p2_slope == p2_p3_slope) { 
// points are collinear 
} 

if(p1.x == p2.x && p1.y == p2.y) { 
    // p1 and p2 overlap 
} 
if(p1.x == p3.x && p1.y == p3.y) { 
    // p1 and p3 overlap 
} 
if(p3.x == p2.x && p3.y == p2.y) { 
    // p3 and p2 overlap 
} 
+0

我們不能使用所有這些精確比較,斜率也可以相反,並仍然表示一個無效的三角形。這些代碼會增加行數並且變得更慢... – abenci 2012-04-16 07:13:28

0

我認爲這確實是

abs(dot(sub(b,a), cross(sub(c,b)))) < epsilon 
如果你只想擴大它,我覺得它的作品了這個

abs((b.x - a.x) * (c.y - b.y) + (b.y - a.y) * (b.x - c.x)) < epsilon 
+0

'abs(dot(b,a),cross(sub(c,b))))'對我來說似乎不正確,可以你檢查嗎? – abenci 2012-04-16 07:11:08