栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【无标题】二进制STL文件解析 计算面积和体积与根据高度计算部分体积

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【无标题】二进制STL文件解析 计算面积和体积与根据高度计算部分体积

场景:容器中存放液体,需要根据雷达测量出的液位计算出容器内的液体体积。
数据:扫描仪扫描容器生成STL文件。
效果图

处理关键代码:
数据结构

/// 
/// 顶点数据结构
/// 
public class Point3
{
    public Point3()
    {
    }

    public Point3(float x = 0, float y = 0, float z = 0)
    {
        X = x;
        Y = y;
        Z = z;
    }
    public float X { get; set; }
    public float Y { get; set; }
    public float Z { get; set; }
}
/// 
/// 三角面数据结构
/// 
public class Face
{
    /// 
    /// 法矢量
    /// 
    public Point3 Vector { get; set; }
   public Point3 P1 { get; set; }
   public Point3 P2 { get; set; }
   public Point3 P3 { get; set; }
    /// 
    /// 三角面片的属性信息
    /// 
    public short Attribute { get; set; }

}

全局变量

 /// 
 /// 三角面集合
 /// 
private List Faces { get; set; }

读取二进制STL文件

byte[] b = null;
try
{
    DtStart = DateTime.Now;
    using (var fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read))
    {

        var length = (int)fs.Length;
        b = new byte[length];
        fs.Read(b, 0, length);
        fs.Close();
    }

}
catch (Exception e)
{
    b = null;
    AddLog(e.Message);
    MessageBox.Show(e.Message);
}

解析三角面数据

if (b == null) return;
var count = BitConverter.ToInt32(b, 80);
for (int i = 0; i < count; i++)
{
    var vx = BitConverter.ToSingle(b, i * 50 + 84);
    var vy = BitConverter.ToSingle(b, i * 50 + 88);
    var vz = BitConverter.ToSingle(b, i * 50 + 92);
    var x1 = BitConverter.ToSingle(b, i * 50 + 96);
    var y1 = BitConverter.ToSingle(b, i * 50 + 100);
    var z1 = BitConverter.ToSingle(b, i * 50 + 104);
    var x2 = BitConverter.ToSingle(b, i * 50 + 108);
    var y2 = BitConverter.ToSingle(b, i * 50 + 112);
    var z2 = BitConverter.ToSingle(b, i * 50 + 116);
    var x3 = BitConverter.ToSingle(b, i * 50 + 120);
    var y3 = BitConverter.ToSingle(b, i * 50 + 124);
    var z3 = BitConverter.ToSingle(b, i * 50 + 128);
    var at = BitConverter.ToInt16(b, i * 50 + 132);

    var face = new Face
    {
        Vector = new Point3(vx, vy, vz),
        P1 = new Point3(x1, y1, z1),
        P2 = new Point3(x2, y2, z2),
        P3 = new Point3(x3, y3, z3),
        Attribute = at
    };
    Faces.Add(face);
}

计算体积和面积

private void Calc()
{
       var v = 0d;
       var s = 0d;
       foreach (var f in Faces)
       {
           v += TriangularVolume(
               f.P1.X, f.P1.Y, f.P1.Z,
               f.P2.X, f.P2.Y, f.P2.Z,
               f.P3.X, f.P3.Y, f.P3.Z);
           s += TriangularArea(
               f.P1.X, f.P1.Y, f.P1.Z,
               f.P2.X, f.P2.Y, f.P2.Z,
               f.P3.X, f.P3.Y, f.P3.Z);
       }

       labelControl1.Text = $@"面积:{(s / 100):F3} cm2{Environment.newline}体积:{(v / 1000):F3} cm3";
   }
    /// 
        /// 计算体积
        /// 
        private double TriangularVolume(float p1X, float p1Y, float p1Z,
            float p2X, float p2Y, float p2Z,
            float p3X, float p3Y, float p3Z)
        {
            double v321 = p3X * p2Y * p1Z;
            double v231 = p2X * p3Y * p1Z;
            double v312 = p3X * p1Y * p2Z;
            double v132 = p1X * p3Y * p2Z;
            double v213 = p2X * p1Y * p3Z;
            double v123 = p1X * p2Y * p3Z;
            return (double)(1.0 / 6.0) * (-v321 + v231 + v312 - v132 - v213 + v123);
        }
        /// 
        /// 计算面积
        /// 
        private double TriangularArea(float p1X, float p1Y, float p1Z,
            float p2X, float p2Y, float p2Z,
            float p3X, float p3Y, float p3Z)
        {
            double ax = p2X - p1X;
            double ay = p2Y - p1Y;
            double az = p2Z - p1Z;
            double bx = p3X - p1X;
            double by = p3Y - p1Y;
            double bz = p3Z - p1Z;
            double cx = ay * bz - az * by;
            double cy = az * bx - ax * bz;
            double cz = ax * by - ay * bx;
            return (double)(0.5 * Math.Sqrt(cx * cx + cy * cy + cz * cz));
        }

对面数据排序

Faces.Sort(((a, b) => b.P1.Z.CompareTo(a.P1.Z)));

UpDown控制步进计算不同高度体积

try
{
     if (Faces == null || Faces.Count == 0) return;
     var t1 = DateTime.Now;
     var spinValue = (float)spinEdit1.Value;
     var v = 0d;
     foreach (var f in Faces)
     {
         if (f.P1.Z <= spinValue)
         {
             v += TriangularVolume(
                 f.P1.X, f.P1.Y, f.P1.Z,
                 f.P2.X, f.P2.Y, f.P2.Z,
                 f.P3.X, f.P3.Y, f.P3.Z);
         }
     }

     var t2 = (DateTime.Now - t1).TotalMilliseconds;
     labelControl2.Text = $@"体积:{(v / 1000):F3} cm3 {Environment.newline}用时:{t2} ms";

 }
 catch (Exception exception)
 {
     Console.WriteLine(exception);
     MessageBox.Show(exception.Message);
 }

源码:

https://download.csdn.net/download/songlinok/70112610

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/690321.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号