示例#1
0
        /// <summary>
        /// Surface: 划分Delaunay三角网,结果保存于tsData
        /// </summary>
        /// <param name="se">曲面插值函数</param>
        public void MeshSurface(SurfaceEquation se)
        {
            try
            {
                triangulations = Triangulation.CreateDelaunay(this.allVerticesList);


                this.TsData.VerticesList = new List <Point3D>(this.allVerticesList.Count);
                this.TsData.TriLinksList = new List <TriLink>(this.triangulations.Cells.Count());

                // 以Dict记录三角形的编号
                int num = 1;
                foreach (var cell in this.triangulations.Cells)
                {
                    for (int i = 0; i < 3; ++i)
                    {
                        var v = cell.Vertices[i];
                        if (!this.vertexnumDictionary.ContainsKey(v))
                        {
                            this.vertexnumDictionary.Add(v, num++);
                        }
                    }

                    // 根据编号写ts的TriLinksList
                    this.TsData.TriLinksList.Add(new TriLink
                    {
                        VertexA = this.vertexnumDictionary[cell.Vertices[0]],
                        VertexB = this.vertexnumDictionary[cell.Vertices[1]],
                        VertexC = this.vertexnumDictionary[cell.Vertices[2]]
                    });
                }

                // 写ts的VerticesList, 并插值Z
                foreach (var kv in this.vertexnumDictionary.OrderBy(n => n.Value))
                {
                    double[] vPos = kv.Key.Position;
                    var      x    = vPos[0];
                    var      y    = vPos[1];
                    var      z    = se.GetInterpolateValue(x, y);

                    this.TsData.VerticesList.Add(new Point3D(x, y, z));
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }
        }
        /// <summary>
        /// 生成曲面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonXBuild_Click(object sender, EventArgs e)
        {
            double attitudeL = this.doubleInputAttitudeLength.Value;
            double shapeR    = this.doubleInputShapeRadium.Value;

            // 生成产状数据集
            double       nx = 0.0, ny = 0.0, nz = 0.0;
            List <Point> sourceAttitudePoints = new List <Point>(this.targetMarkersList.Count * 4);

            foreach (var marker in this.targetMarkersList)
            {
                nx += Math.Sin(marker.MyDip * Math.PI / 180) * Math.Sin(marker.MyAngle * Math.PI / 180)
                      / this.targetMarkersList.Count;
                ny += Math.Cos(marker.MyDip * Math.PI / 180) * Math.Sin(marker.MyAngle * Math.PI / 180)
                      / this.targetMarkersList.Count;
                nz += Math.Cos(marker.MyAngle * Math.PI / 180) / this.targetMarkersList.Count;


                double dx         = -Math.Tan(marker.MyAngle * Math.PI / 180) * Math.Cos(marker.MyDip * Math.PI / 180);
                double dy         = -Math.Tan(marker.MyAngle * Math.PI / 180) * Math.Sin(marker.MyDip * Math.PI / 180);
                Point  northPoint = new Point(
                    marker.X,
                    marker.Y + attitudeL,
                    marker.Z + dy * attitudeL);
                Point southPoint = new Point(
                    marker.X,
                    marker.Y - attitudeL,
                    marker.Z - dy * attitudeL);
                Point eastPoint = new Point(
                    marker.X + attitudeL,
                    marker.Y,
                    marker.Z + dx * attitudeL);
                Point westPoint = new Point(
                    marker.X - attitudeL,
                    marker.Y,
                    marker.Z - dx * attitudeL);

                sourceAttitudePoints.AddRange(new[] { northPoint, southPoint, eastPoint, westPoint });
            }

            Point middlePoint = CurveAlgorithm.MiddlePointOfPoints(this.targetMarkersList);

            // 平均产状平面
            Vector3D n     = new Vector3D(nx, ny, nz);
            var      plane = new MathNet.Spatial.Euclidean.Plane(
                new Point3D(middlePoint.X, middlePoint.Y, middlePoint.Z),
                n.Normalize());

            double a0 = -plane.D / plane.C;
            double a1 = -plane.A / plane.C;
            double a2 = -plane.B / plane.C;

            // 插值点数据集
            List <Point> sourcePoints = new List <Point>(this.targetMarkersList);

            sourcePoints.AddRange(sourceAttitudePoints);

            SurfaceEquation surfaceEquation = new SurfaceEquation(a0, a1, a2, sourcePoints, shapeR);

            // 确定曲面区域
            List <Point> edgePoints = CurveAlgorithm.GetEdgePoints(sourcePoints, this.GridEdgeLength);

            // 区域内插加密点 GeoHelper.InsertPointsInPolygon
            List <Point> pointsList = GeoHelper.InsertPointsInPolygon(edgePoints, this.GridEdgeLength);

            // 生成网格 Triangulations
            Triangulations tris = new Triangulations(pointsList, new List <Point>());

            // 计算插值 SurfaceMesh
            tris.MeshSurface(surfaceEquation);

            // 绘制曲面
            IColor66 fillColor = this.sgworld.Creator.CreateColor(128, 128, 128, 128);
            IColor66 lineColor = this.sgworld.Creator.CreateColor(255, 255, 255, 0);

            var parentGid = GeoHelper.CreateGroup("产状地质曲面", ref this.sgworld);



            Facet facet = new Facet(ref this.sgworld, tris.TsData, "Test", parentGid, lineColor, fillColor);

            // facet.DrawFacet();

            // 保存三角网结果
            TsFile ts = new TsFile(
                tris.TsData,
                "TSurf",
                "M",
                "JGM",
                "Name",
                new List <string>());

            ts.WriteTsFile();
            ts.UpdateTsFile(ref this.db);

            ToastNotification.Show(this, "曲面模型已保存为模型部件", 2500, eToastPosition.MiddleCenter);
        }