C# VTK 自定义封装 vtkwPipeline 多边形管道建模

vtkwPipeline 简介

   public vtkwPipeline(vtkLineSource lineSource, double outR, double inR, int sides)

vtkwPipeline  是我自定义封装的C# 类 用于对管道壁建模,有内半径,外半径设置,

以及多边形边数设置。

参数

1. vtkLineSource lineSource : 建模的管道路径

2.double outR:外半径

3.double inR: 内半径

4.int sides: 多边形边数

建模逻辑步骤

1.对lineSource第一个点进行 vtkRegularPolygonSource 内外多边形点集构建。

2.利用这个初始pipeFace 一直向下一个点直线移动,直到第二点停止,然后进行节点的角度旋转。

3.构建节点的夹角plane 将两个pipeFace 对应点连接为中心对plane 求进行直线交点,生成节点的pipeFace。

    public class vtkwPipeline
    {
        vtkCellArray Plane;
        vtkPoints Points;
        vtkPolyData PolyData;
        double OutRadius = 2;
        double InRadius = 1;
        int Sides = 30;
        vtkLineSource LineSource;
        public vtkwPipeline(vtkLineSource lineSource, double outR, double inR, int sides)
        {
            LineSource = lineSource;

            outR = Math.Abs(outR);
            inR = Math.Abs(inR);
            (OutRadius, InRadius) = outR > inR ? (outR, inR) : (inR, outR);

            Sides = sides;

            Plane = new vtkCellArray();
            Points = new vtkPoints();
            PolyData = new vtkPolyData();
        }

        public void Update()
        {
            if (LineSource == null || LineSource.GetOutput().GetNumberOfPoints() <= 1)
            {
                return;
            }

            vtkPoints linePoints = LineSource.GetOutput().GetPoints();

            double[] first = linePoints.GetPoint(0);
            double[] next = linePoints.GetPoint(1);

            double[] norm = new double[3] { next[0] - first[0], next[1] - first[1], next[2] - first[2] };
            PipeFace lastPipeFace = new PipeFace(first, norm, OutRadius, InRadius, Sides);
            lastPipeFace.InsertPoints(ref Points);
            lastPipeFace.CellFace(ref Plane);
            PipeFace lastCalcuPipeFace = lastPipeFace;
            PipeFace nextPipeFace = new PipeFace();
            for (int i = 1; i < linePoints.GetNumberOfPoints(); i++)
            {
                nextPipeFace = new PipeFace();
                if (i == linePoints.GetNumberOfPoints() - 1)
                {
                    first = linePoints.GetPoint(i - 1);
                    next = linePoints.GetPoint(i);

                    norm = new double[3] { next[0] - first[0], next[1] - first[1], next[2] - first[2] };
                    double[] moveValue = norm;
                    nextPipeFace = new PipeFace(lastPipeFace, moveValue, 0, new double[] { 0, 0, 0 });
                    nextPipeFace.InsertPoints(ref Points);
                    nextPipeFace.CellFace(ref Plane);
                }
                else
                {
                    first = linePoints.GetPoint(i - 1);
                    next = linePoints.GetPoint(i);

                    norm = new double[3] { next[0] - first[0], next[1] - first[1], next[2] - first[2] };
                    double[] moveValue = norm;

                    // 移动到末端节点
                    double[] trid = linePoints.GetPoint(i + 1);

                    PipeFace nodePipe_1 = new PipeFace(lastPipeFace, moveValue, 0, new double[] { 0, 0, 0 });

                    double[] normNext = new double[3] { trid[0] - next[0], trid[1] - next[1], trid[2] - next[2] };
                    double[] rotNorm = CrossProduct(normNext, norm);
                    double rotValue = CalculateAngle(normNext, norm);

                  
                    PipeFace nodePipe_2 = new PipeFace(nodePipe_1, new double[] { 0, 0, 0 }, rotValue, rotNorm);

                    // 计算偏移
                    double[] norm2 = new double[3] { trid[0] - next[0], trid[1] - next[1], trid[2] - next[2] };
                    double dis = CalculateDistance(first, next);
                    norm2 = NormalizeVector(norm2);
                    double[] tempPoint = MovePoint(next, norm2, dis);
                    norm2 = new double[3] { tempPoint[0] - first[0], tempPoint[1] - first[1], tempPoint[2] - first[2] };
                    norm2 = NormalizeVector(norm2);
                    vtkPlane plane = new vtkPlane();
                    plane.SetNormal(norm2[0], norm2[1], norm2[2]);
                    plane.SetOrigin(next[0], next[1], next[2]);

                    vtkPoints outPoints_1 = new vtkPoints();
                    outPoints_1.DeepCopy(lastPipeFace.outPoints);
                    vtkPoints inPoints_1 = new vtkPoints();
                    inPoints_1.DeepCopy(lastPipeFace.intPoints);

                    vtkPoints outPoints_2 = new vtkPoints();
                    outPoints_2.DeepCopy(nodePipe_1.outPoints);
                    vtkPoints inPoints_2 = new vtkPoints();
                    inPoints_2.DeepCopy(nodePipe_1.intPoints);

                    // 投影到交界平面
                    for (int k = 0; k < outPoints_2.GetNumberOfPoints(); k++)
                    {
                        double[] pout1 = outPoints_1.GetPoint(k);
                        double[] pin1 = inPoints_1.GetPoint(k);
                        IntPtr pOut1Ptr = Marshal.AllocCoTaskMem(sizeof(double) * 3);
                        Marshal.Copy(pout1, 0, pOut1Ptr, 3);

                        IntPtr pIn1Ptr = Marshal.AllocCoTaskMem(sizeof(double) * 3);
                        Marshal.Copy(pin1, 0, pIn1Ptr, 3);

                        double[] pout2 = outPoints_2.GetPoint(k);
                        double[] pin2 = inPoints_2.GetPoint(k);
                        IntPtr pOut2Ptr = Marshal.AllocCoTaskMem(sizeof(double) * 3);
                        Marshal.Copy(pout2, 0, pOut2Ptr, 3);

                        IntPtr pIn2Ptr = Marshal.AllocCoTaskMem(sizeof(double) * 3);
                        Marshal.Copy(pin2, 0, pIn2Ptr, 3);

                        // 外圈偏移点
                        double t = 0;
                        IntPtr outPtr = Marshal.AllocCoTaskMem(sizeof(double) * 3);
                        plane.IntersectWithLine(pOut1Ptr, pOut2Ptr, ref t, outPtr);

                        Marshal.Copy(outPtr, pout2, 0, 3);
                        outPoints_2.SetPoint(k, pout2[0], pout2[1], pout2[2]);

                        // 内圈偏移点
                        IntPtr inPtr = Marshal.AllocCoTaskMem(sizeof(double) * 3);
                        plane.IntersectWithLine(pIn1Ptr, pIn2Ptr, ref t, inPtr);

                        Marshal.Copy(inPtr, pin2, 0, 3);
                        inPoints_2.SetPoint(k, pin2[0], pin2[1], pin2[2]);
                    }

                    nextPipeFace.center = next;
                    nextPipeFace.outPoints = outPoints_2;
                    nextPipeFace.intPoints = inPoints_2;
                    nextPipeFace.InsertPoints(ref Points);
                    nextPipeFace.CellFace(ref Plane);

                    lastPipeFace = nodePipe_2;
                }


                PipeFace.CellArray(lastCalcuPipeFace, nextPipeFace, ref Plane);


                lastCalcuPipeFace = nextPipeFace;
            }
            PolyData = new vtkPolyData();
            PolyData.SetPoints(Points);
            PolyData.SetStrips(Plane);


        }

        public vtkPolyData GetOutput()
        {
            return PolyData;
        }

        public static double CalculateAngle(double[] vectorA, double[] vectorB)
        {
            // 检查向量长度是否相等
            if (vectorA.Length != 3 || vectorB.Length != 3)
            {
                throw new ArgumentException("Both vectors must be 3-dimensional.");
            }

            // 计算点积
            double dotProduct = vectorA[0] * vectorB[0] + vectorA[1] * vectorB[1] + vectorA[2] * vectorB[2];

            // 计算两个向量的模
            double magnitudeA = Math.Sqrt(vectorA[0] * vectorA[0] + vectorA[1] * vectorA[1] + vectorA[2] * vectorA[2]);
            double magnitudeB = Math.Sqrt(vectorB[0] * vectorB[0] + vectorB[1] * vectorB[1] + vectorB[2] * vectorB[2]);

            // 计算夹角的余弦值
            double cosTheta = dotProduct / (magnitudeA * magnitudeB);

            // 防止浮点误差引起的 Math.Acos 域错误
            cosTheta = Math.Max(-1.0, Math.Min(1.0, cosTheta));

            // 计算并返回夹角(以弧度为单位)
            double angleInRadians = Math.Acos(cosTheta);

            // 将弧度转换为度数(如果需要)
            double angleInDegrees = angleInRadians * (180.0 / Math.PI);

            return angleInDegrees;
        }

        public static double[] NormalizeVector(double[] vector)
        {
            // 检查向量长度是否为3
            if (vector.Length != 3)
            {
                throw new ArgumentException("The input vector must be 3-dimensional.");
            }

            // 计算向量的模
            double magnitude = Math.Sqrt(vector[0] * vector[0] + vector[1] * vector[1] + vector[2] * vector[2]);

            // 检查向量模是否为零
            if (magnitude == 0)
            {
                return vector;
                throw new ArgumentException("The magnitude of the vector is zero, cannot normalize.");
            }

            // 计算单位化向量
            double[] normalizedVector = new double[3];
            normalizedVector[0] = vector[0] / magnitude;
            normalizedVector[1] = vector[1] / magnitude;
            normalizedVector[2] = vector[2] / magnitude;

            return normalizedVector;
        }

        public static double CalculateDistance(double[] p1, double[] p2)
        {
            // 计算各坐标的差值
            double dx = p2[0] - p1[0];
            double dy = p2[1] - p1[1];
            double dz = p2[2] - p1[2];

            // 使用欧几里得距离公式计算距离
            double distance = Math.Sqrt(dx * dx + dy * dy + dz * dz);
            return distance;
        }

        public static double[] CrossProduct(double[] vectorA, double[] vectorB)
        {
            // 检查向量长度是否为3
            if (vectorA.Length != 3 || vectorB.Length != 3)
            {
                throw new ArgumentException("Both vectors must be 3-dimensional.");
            }

            // 计算叉积
            double[] crossProduct = new double[3];
            crossProduct[0] = vectorA[1] * vectorB[2] - vectorA[2] * vectorB[1];
            crossProduct[1] = vectorA[2] * vectorB[0] - vectorA[0] * vectorB[2];
            crossProduct[2] = vectorA[0] * vectorB[1] - vectorA[1] * vectorB[0];

            return crossProduct;
        }

        public static double[] MovePoint(double[] point, double[] direction, double distance)
        {
            if (point.Length != 3 || direction.Length != 3)
            {
                throw new ArgumentException("Both the point and direction vector must be 3-dimensional.");
            }

            // 计算方向向量的模
            double magnitude = Math.Sqrt(direction[0] * direction[0] + direction[1] * direction[1] + direction[2] * direction[2]);

            // 单位化方向向量
            double[] unitDirection = new double[3];
            unitDirection[0] = direction[0] / magnitude;
            unitDirection[1] = direction[1] / magnitude;
            unitDirection[2] = direction[2] / magnitude;

            // 计算移动向量
            double[] moveVector = new double[3];
            moveVector[0] = unitDirection[0] * distance;
            moveVector[1] = unitDirection[1] * distance;
            moveVector[2] = unitDirection[2] * distance;

            // 更新点的位置
            double[] newPoint = new double[3];
            newPoint[0] = point[0] + moveVector[0];
            newPoint[1] = point[1] + moveVector[1];
            newPoint[2] = point[2] + moveVector[2];

            return newPoint;
        }

        public class PipeFace
        {
            public double[] center;
            public vtkPoints outPoints;
            public vtkPoints intPoints;
            public List<int> outId = new List<int>();
            public List<int> inId = new List<int>();
            public PipeFace()
            {

            }

            public PipeFace(double[] cen, double[] norm, double outRadius, double inRadius, int sides)
            {
                center = cen;
                outPoints = GeneratePolygonPoints(center, norm, outRadius, sides);
                intPoints = GeneratePolygonPoints(center, norm, inRadius, sides);
            }

            public PipeFace(PipeFace lastPipeFace, double[] moveValue, double rotValue, double[] rotNorm)
            {
                TransPipeFace(lastPipeFace, moveValue, rotValue, rotNorm);
            }

            public void TransPipeFace(PipeFace lastPipeFace, double[] moveValue, double rotValue, double[] rotNorm)
            {
                vtkPolyData outPointData = new vtkPolyData();
                outPointData.SetPoints(lastPipeFace.outPoints);

                vtkPolyData inPointData = new vtkPolyData();
                inPointData.SetPoints(lastPipeFace.intPoints);
                center = lastPipeFace.center;
                center[0] = lastPipeFace.center[0] + moveValue[0];
                center[1] = lastPipeFace.center[1] + moveValue[1];
                center[2] = lastPipeFace.center[2] + moveValue[2];

                rotNorm = NormalizeVector(rotNorm);
                vtkTransform transform = new vtkTransform();
                transform.Translate(moveValue[0], moveValue[1], moveValue[2]);
                transform.Translate(center[0], center[1], center[2]);
                transform.RotateWXYZ(-rotValue, rotNorm[0], rotNorm[1], rotNorm[2]);
                transform.Translate(-center[0], -center[1], -center[2]);
                transform.Update();

                vtkTransformFilter transFilter = new vtkTransformFilter();
                transFilter.SetInputData(outPointData);
                transFilter.SetTransform(transform);
                transFilter.Update();

                outPoints = transFilter.GetOutput().GetPoints();

                transFilter.SetInputData(inPointData);
                transFilter.SetTransform(transform);
                transFilter.Update();

                intPoints = transFilter.GetOutput().GetPoints();

                double[] cen2 = transFilter.GetOutput().GetCenter();
            }

            public void InsertPoints(ref vtkPoints points)
            {
                if (outPoints != null && intPoints != null)
                {

                    for (int n = 0; n < outPoints.GetNumberOfPoints(); n++)
                    {
                        double[] pos = outPoints.GetPoint(n);
                        int id = (int)points.InsertNextPoint(pos[0], pos[1], pos[2]);
                        outId.Add(id);
                    }

                    for (int k = 0; k < intPoints.GetNumberOfPoints(); k++)
                    {
                        double[] pos = intPoints.GetPoint(k);
                        int id = (int)points.InsertNextPoint(pos[0], pos[1], pos[2]);
                        inId.Add(id);
                    }
                }
            }

            public void CellFace(ref vtkCellArray plane)
            {
                int npts = outId.Count + inId.Count;
                if (npts == 0)
                {
                    return;
                }

                plane.InsertNextCell(npts + 2);
                for (int n = 0; n < outId.Count; n++)
                {
                    plane.InsertCellPoint(outId[n]);
                    plane.InsertCellPoint(inId[n]);
                }

                plane.InsertCellPoint(outId[0]);
                plane.InsertCellPoint(inId[0]);
            }

            public vtkPoints GeneratePolygonPoints(double[] center, double[] norm, double radius, int sides)
            {
                vtkRegularPolygonSource polygonSource = new vtkRegularPolygonSource();
                polygonSource.SetCenter(center[0], center[1], center[2]);
                polygonSource.SetNormal(norm[0], norm[1], norm[2]);
                polygonSource.SetRadius(radius);
                polygonSource.SetNumberOfSides(sides);
                polygonSource.SetGeneratePolygon(1);
                polygonSource.SetGeneratePolyline(1);
                polygonSource.Update();

                vtkStripper stripper = new vtkStripper();
                stripper.SetInputData(polygonSource.GetOutput());
                stripper.JoinContiguousSegmentsOn();
                stripper.Update();
                return stripper.GetOutput().GetPoints();
            }

            public static void CellArray(PipeFace pipe1, PipeFace pipe2, ref vtkCellArray plane)
            {
                int inNpts = pipe1.inId.Count + pipe2.inId.Count;

                // 内外条带
                plane.InsertNextCell(inNpts + 2);
                for (int n = 0; n < pipe1.inId.Count; n++)
                {
                    plane.InsertCellPoint(pipe1.inId[n]);
                    plane.InsertCellPoint(pipe2.inId[n]);
                }

                plane.InsertCellPoint(pipe1.inId[0]);
                plane.InsertCellPoint(pipe2.inId[0]);

                int outNpts = pipe1.outId.Count + pipe2.outId.Count;
                plane.InsertNextCell(outNpts + 2);
                for (int n = 0; n < pipe1.outId.Count; n++)
                {
                    plane.InsertCellPoint(pipe1.outId[n]);
                    plane.InsertCellPoint(pipe2.outId[n]);
                }

                plane.InsertCellPoint(pipe1.outId[0]);
                plane.InsertCellPoint(pipe2.outId[0]);
            }
        }

    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/748688.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

EI CCIE学习笔记-SDAccess之一:SDAccess解决方案

Chapter 1 SD-Access Solution Proposal 1.1 概念引入 SDN三要素&#xff1a;集中控制、转控分离、可编程 DNA DNA:Digital Network Architecture数字网络架构 思科提出的跨园区&#xff0c;分支机构&#xff0c;WAN和扩展企业的企业网络架构它提供了一种开放&#xff0c;可扩…

win10 C:\Users\Administrator

win10 C:\Users\Administrator C:\Users\Administrator\Documents\ C:\Users\Administrator\Pictures C:\Users\Administrator\Favorites C:\Users\Administrator\Links C:\Users\Administrator\Videos

Shopee API接口——获取商家店铺商品列表

一、引言 在跨境电商领域&#xff0c;Shopee作为东南亚地区领先的电商平台&#xff0c;为众多商家提供了广阔的市场和丰富的销售机会。本文将详细介绍如何通过Shopee API获取商家店铺商品列表&#xff0c;并探讨其应用场景。 二、核心功能介绍 Shopee API获取商家店铺商品列…

数据结构(Java):ArrayList的应用

1、引言 上一篇博客&#xff0c;已经为大家讲解了集合类ArrayList。 这篇博客&#xff0c;就来帮助大家学会使用ArrayList。 2、题1&#xff1a; 删除字符&#xff08;热身题&#xff09; 题目&#xff1a;给出str1和str2两个字符串&#xff0c;删除str1中出现的所有的str2…

【线代基础】张宇30讲+300题错题整理

第一章 行列式 1. 2. 第二章 矩阵 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 第三章 向量 1. 2. 3. 第四章 线性方程组 1. 2. 3. 4. 5. 6. 7. 8. 9. 第五章 特征值与特征向量 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 第六章 二次型 1. 2. 3. 4. 5. 终于结束了线性…

【Mysql】多表关系设计

多表关系设计 实际开发中&#xff0c;一个项目通常需要很多张表才能完成。例如&#xff1a;一个商城项目就需要分类表(category)、商品表(products)、订单表(orders)等多张表。且这些表的数据之间存在一定的关系&#xff0c;接下来我们一起学习一下多表关系设计方面的知识 一对…

系统性掌握C++17容器四件套:std::optional, std::any, std::variant, std::tuple

昨天在写《深入探讨C的高级反射机制&#xff08;2&#xff09;&#xff1a;写个能用的反射库》的时候&#xff0c;正好遇到动态反射需要的类型擦除技术。所谓的类型擦除&#xff0c;就是在两个模块之间的接口层没有任何类型信息&#xff0c;实现两个模块之间安全的通信。可以理…

Unity3D Text使用超链接跳转事件

系列文章目录 Unity工具 文章目录 系列文章目录&#x1f449;前言&#x1f449;一、第一种使用TextMeshPro加入超链接&#x1f449;二、继承Text组件,重载OnPopulateMesh方法&#x1f449;三.壁纸分享&#x1f449;总结 &#x1f449;前言 有时候会用到跳转的问题,所以添加一…

Flutter第十五弹 Flutter插件

目标&#xff1a; 1.Flutter插件是什么&#xff1f;有什么作用&#xff1f; 2.怎么创建Flutter插件&#xff1f; 一、什么是插件 在flutter中&#xff0c;一个插件叫做一个package&#xff0c;使用packages的目的就是为了达到模块化&#xff0c;可以创建出可被复用和共享的代…

关于PX4模拟机型的拓展

#多旋翼 #四旋翼&#xff08;默认&#xff09; sudo make px4_sitl gazebo #带光流的四旋翼 sudo make px4_sitl gazebo_iris_opt_flow #3DR Solo&#xff08;四旋翼&#xff09; sudo make px4_sitl gazebo_solo #Typhoon H480&#xff08;六旋翼&#xff09; sudo make px4_s…

超声波清洗机对眼镜有伤害吗?四大顶尖优品公认力作!

超声波清洗机利用超声波在液体中产生的微小气泡爆炸&#xff0c;产生强大的冲击力&#xff0c;能够深入物品的各个角落&#xff0c;有效去除油污、灰尘和细菌。与传统的手工清洗相比&#xff0c;不仅清洁效率高&#xff0c;而且能够保护眼镜不受损伤&#xff0c;特别适合清洗眼…

海纳斯 hinas 的hi3798mv100 华为悦盒 6108v9 安装wifi模块

hi3798mv100安装wifi模块 1.执行脚本 &#xff0c;执行完毕后重启服务器2. 继续执行脚本3.检查网卡驱动安装是否正确4.查看网卡安装状态5.连接wifi结尾 1.执行脚本 &#xff0c;执行完毕后重启服务器 bash <(curl -sSL https://gitee.com/xjxjin/scripts/raw/main/install_…

7km远距离WiFi实时图传模块,无人机海上无线传输方案,飞睿智能WiFi MESH自组网技术

在浩瀚无垠的海洋上&#xff0c;无人机正在开启一场前所未有的技术创新。它们不再只是天空的舞者&#xff0c;更是海洋的守望者&#xff0c;为我们带来前所未有的视野和数据。而这一切的背后&#xff0c;都离不开一项创新性的技术——飞睿智能远距离WiFi实时图传模块与无线Mesh…

链式队列算法库构建

学习贺利坚老师课程,构建链式队列算法库 数据结构之自建算法库——链队&#xff08;链式队列&#xff09;_数据结构函数链队列的算法框架有哪些-CSDN博客文章浏览阅读6.2k次&#xff0c;点赞3次&#xff0c;收藏9次。本文针对数据结构基础系列网络课程(3)&#xff1a;栈和队列…

机器学习--概念理解

知识点 一、机器学习概述 人工智能 机器学习 深度学习 学习的范围&#xff1a;模式识别、数据挖掘、统计学习、计算机视觉、语音识别、自然语言处理 可以解决的问题&#xff1a;给定数据的预测问题 二、机器学习的类型 监督学习 分类 回归 无监督学习 聚类 降维 强化…

iOS项目开发遇到问题杂项坑点记录

ios17 弹窗UIAlertController展示逻辑变化&#xff0c;单个词一行展示不下不换行&#xff08;这前版本会换行&#xff09;&#xff0c;直接截断超出部分。 UINavigationController push立刻pop会异常&#xff0c;使用用setViewCollerllers可以避免这个问题 键盘切换后立刻切页…

【React Native】measureInWindow在安卓上无法正确获取View在屏幕上的布局信息

问题描述&#xff1a; 在React Native中&#xff0c;我们可以使用measureInWindow的方式去获取一个View在屏幕中的位置信息&#xff1a; 下面这个Demo中&#xff0c;我们写了一个页面HomePage和一个列表项组件ListItemA&#xff0c;我们期望每过5s监测一次列表中每一项在屏幕中…

通过搭建 24 点小游戏应用实战,带你了解 AppBuilder 的技术原理

本文将通过一个 24 点小游戏的案例&#xff0c;详细介绍百度智能云千帆 AppBuilder 的基本技术原理和使用方法&#xff0c;帮助读者快速掌握 AI 原生应用的开发流程。 1 三步构建 AI 原生应用方法论 AI 原生应用与传统应用的最大区别是交互形态彻底的拟人化&#xff0c;通过文…

【Linux学习十八】网站管理:防火墙介绍、静态站点、动态站点、域名

1.Apache Apache官网: www.apache.org 软件包名称: httpd 服务端口:80/tcp(http) 443/tcp(https) 配置文件: /etc/httpd/conf/httpd.conf 子配置文件:/etc/httpd/conf.d/*.conf 查看被占用的端口号 netstat -tuln | grep <端口号> 解哪个程序正在使用端口 80&#xff0…

vue封装原生table表格方法

适用场景&#xff1a;有若干个表格&#xff0c;前面几列格式不一致&#xff0c;但是后面几列格式皆为占一个单元格&#xff0c;所以需要封装表格&#xff0c;表格元素自动根据数据结构生成即可&#xff1b;并且用户可新增列数据。 分类&#xff1a; 固定数据部分 就是根据数据…