用XYZ坐标计算对象体积

时间:2019-10-08 10:54:06

标签: c# .net winforms 3d

我的Winforms应用程序从3D摄像机获取具有XYZ坐标的CSV文件。使用这些坐标,我需要以立方分米(dm3)为单位计算对象的体积。

我不知所措,不是数学专家。我本来希望是已经做到这一点的库或算法,但是我发现的唯一东西是在C ++中,例如PCL库,或者它们使用Unity。对于像我这样不懂几何的人,有没有一种简单/干净的方法来获取带有XYZ坐标的对象的体积?

更新

这是到目前为止的代码片段:

public class Volume
{
    //These are only part of the coordinates in the CSV file. There are more than 69.000 lines
    Vector3[] vectors = new Vector3[8]
        {
            new Vector3 {X=-139,Y=-109,Z=285},
            new Vector3 {X=-138,Y=-109,Z=286},
            new Vector3 {X=-136,Y=-109,Z=286},
            new Vector3 {X=-135,Y=-109,Z=286},
            new Vector3 {X=-133,Y=-109,Z=286},
            new Vector3 {X=-132,Y=-109,Z=286},
            new Vector3 {X=-130,Y=-109,Z=286},
            new Vector3 {X=-129,Y=-109,Z=286}
        };

    public double VolumeOfMesh()
    {
        Mesh _mesh = new Mesh();
        double volume = 0.0;

        _mesh.Vertices = vectors; //Should the vectors be organized by proximity to create the triangles?
        _mesh.Triangles = null; //How do I calculate the triangles?

        Vector3[] vertices = _mesh.Vertices;
        int[] triangles = _mesh.Triangles;

        for (int i = 0; i < _mesh.Triangles.Length; i += 3)
        {
            Vector3 p1 = vertices[triangles[i + 0]];
            Vector3 p2 = vertices[triangles[i + 1]];
            Vector3 p3 = vertices[triangles[i + 2]];

            volume += SignedVolumeOfTriangle(p1, p2, p3);
        }

        return Math.Abs(volume);
    }

    private double SignedVolumeOfTriangle(Vector3 p1, Vector3 p2, Vector3 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.0 / 6.0) * (-v321 + v231 + v312 - v132 - v213 + v123);
    }
}

向量数组应该按接近度排序吗?如何填充Triangles属性?

任何建议或指导都将受到欢迎。

1 个答案:

答案 0 :(得分:2)

这就是我使用.STL文件将点排列成三角形面的方式。对于您的情况,您需要以某种方式描述结合哪些点(节点)以定义面,并确保这些面形成闭合的水密实体。

wedge

这个想法是形成面孔的每三个点 ABC 与原点一起形成一个体积实体

volume

,其中·是矢量点积,×是矢量叉积。

事实证明,当您将所有体积相加时,一些将为正(背离原点),而某些将为负(面向原点)。最后,总和等于对象的封闭体积。

这里是colname_list = dataframe.columns.tolist() #find 'int' columns int_df = dataframe.select_dtypes(include='int64') int_name_list = int_df.columns.tolist() # change them into 'int32' for i in range(len(int_name_list)): dataframe[int_name_list[i]] = dataframe[int_name_list[i]].astype('int32') name_dict = {} for i in range(dataframe.shape[0]): node = Node(dataframe[colname_list[0]][0]) for j in range(dataframe.shape[1]): name_dict[j] = str(dataframe.iloc[i, :][colname_list[j]]) attr = dataframe.iloc[i][colname_list[j]] node[colname_list[j]] = attr r = Relationship(node, "Belong to", node_table) graph.create(node) graph.create(r) 代码的示例,我正在使用该代码从网格获取实体对象属性。请记住,网格是由顶点中三个点的索引值定义的C#点集合和称为Nodes的三角形集合。

Faces

作为测试用例,我只使用了一个定义如下的三角形:

  

example1   example2

此外,通过将上述计算结果与商业CAD软件包产生的结果进行比较,我以更复杂的形状验证了结果。

example3