2009-09-10 1 views
37

Я хочу рассчитать объем 3D-сетчатого объекта с треугольными поверхностями.Как рассчитать объем 3D-сетчатого объекта, поверхность которого состоит из треугольников

+3

У меня нет времени, чтобы дать вам больше информации, может быть, кто-то еще кулачок, но посмотрите: http://amp.ece.cmu.edu/Publication/Cha/icip01_Cha.pdf – nlucaroni

+0

Появляется избыточным с вопросом 1410525 – DarenW

ответ

4

GNU Triangulated Surface Librarycan do this for you. Имейте в виду, что поверхность должна быть закрыта. Это не относится к довольно многим 3D-моделям.

Если вы хотите реализовать его самостоятельно, вы можете начать с изучения их кода.

+7

Если вы это сделаете, будьте осторожны - библиотека GTS является LGPL, поэтому любая производная работа должна быть LGPL или GPL. – Cascabel

-1

Если вы правильно поняли, вы говорите, что у вас уже есть поверхностная сетка треугольников, и вы хотите создать из нее трехмерную сплошную сетку.

Треугольники означают, что вам придется использовать тетраэдрические элементы для 3D-интерьера. Вы хотите найти octree auto meshing algorithm, который может принимать поверхностную сетку в качестве семени.

Это распространенная проблема в литературе конечного элемента автосоединения. Я бы посмотрел.

59

Reading this paper, на самом деле довольно простой расчет.

Трюк состоит в том, чтобы рассчитать подписанный том тетраэдра - основанный на вашем треугольнике и завершенный в начале координат. Знак объема исходит из того, указывает ли ваш треугольник в направлении начала координат. (Нормальный треугольника сама зависит от порядка ваших вершин, поэтому вы не видите это указано явно ниже.)

Это все сводится к следующей простой функции:

public float SignedVolumeOfTriangle(Vector p1, Vector p2, Vector p3) { 
    var v321 = p3.X*p2.Y*p1.Z; 
    var v231 = p2.X*p3.Y*p1.Z; 
    var v312 = p3.X*p1.Y*p2.Z; 
    var v132 = p1.X*p3.Y*p2.Z; 
    var v213 = p2.X*p1.Y*p3.Z; 
    var v123 = p1.X*p2.Y*p3.Z; 
    return (1.0f/6.0f)*(-v321 + v231 + v312 - v132 - v213 + v123); 
} 

, а затем драйвер для вычисления объема сетки:

public float VolumeOfMesh(Mesh mesh) { 
    var vols = from t in mesh.Triangles 
       select SignedVolumeOfTriangle(t.P1, t.P2, t.P3); 
    return Math.Abs(vols.Sum()); 
} 
+1

Довольно элегантное решение. – levis501

+0

Мне интересно, почему это не было обнаружено до 2001 года. Или это было, но не имело никакого отношения? –

+1

Oct 1984 опубликован документ «Символический метод вычисления интегральных свойств произвольных невыпуклых многогранников» и описывается этот метод для вычисления объема. Это также более или менее тривиальный метод, поэтому вам нужно гораздо больше, чем просто эту информацию, чтобы опубликовать документ. –

14

Yip Frank Kruegers ответ хорошо работает +1 за это. Если у вас есть векторные функции, вы можете использовать это также:

public static float SignedVolumeOfTriangle(Vector p1, Vector p2, Vector p3) 
    { 
     return p1.Dot(p2.Cross(p3))/6.0f; 
    } 

изменить .. добавлен impl. для Dot() и Cross(), если вы не уверены. Большинство Math libs будут иметь их. Если вы используете WPF, они реализуются как статические методы класса Vector3D.

public class Vector 
    { 
     ... 

     public float Dot(Vector a) 
     { 
      return this.X * a.X + this.Y * a.Y + this.Z * a.Z; 
     } 

     public Vector Cross(Vector a) 
     { 
      return new Vector(
       this.Y * a.Z - this.Z * a.Y, 
       this.Z * a.X - this.X * a.Z, 
       this.X * a.Y - this.Y * a.X 
      ); 
     } 
     ... 
    } 
+0

, возможно, почтовый код для Dot() AND Cross()? (как тривиальные для реализации, так и для полноты). BTW, @Frank Kruegers ответ - это то, что вы получаете, если упростите p1.Dot (p2.Cross (p3))/6.0f –

1

Описанный выше метод является правильным для «простых» объектов (не пересекающихся/перекрывающиеся треугольники) как сферы tetrahedras и так далее. Для более сложных форм хорошей идеей может быть сегмент сетки (закройте ее) и вычислить объем каждого сегмента отдельно. Надеюсь, это поможет.

+3

, если объем подписан, вам не нужно, чтобы центр находился внутри – makc

+1

Неверный ответ. Описанный метод верен для сколь угодно сложных замкнутых объектов без пересекающихся/перекрывающихся треугольников, и нет требования о расположении центральной точки. Это потому, что «тома» тетраэдра подписываются и добавляют алгебраически. – galinette

+0

@ galinette Да, вы правы. Под «простыми» объектами я имел в виду объекты без пересекающихся/перекрывающихся треугольников. Также центр сетки может быть снаружи. – imoutidi