2012-04-12 6 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

Нулевая область должна быть результатом коллинеарных точек или перекрывающихся точек (как вы упомянули). так почему бы просто не проверить эти 2 условия? гораздо дешевле, я думаю. –

ответ

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

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 (точка (sub (b, a), cross (sub (c, b))))' не кажется мне правильным, может вы проверяете пожалуйста? – abenci

Смежные вопросы