zoukankan      html  css  js  c++  java
  • C# CAD 凹凸点识别最大轮廓

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Beaver.Unfold.Core
    {
        /// <summary>
        /// 最大凹凸面
        /// </summary>
        public class Csharp_Delauney
        {
            // ---------------------------------------------------------------
            // ---------------------------------------------------------------
            // ---------------------------------------------------------------
            //Points (Vertices)
            public struct dVertex
            {
                public double x;
                public double y;
                public double z;
            }
    
            //Created Triangles, vv# are the vertex pointers
            public struct dTriangle
            {
                public int vv0;
                public int vv1;
                public int vv2;
            }
    
            //Set these as applicable
            public int MaxVertices = 1500;
            public int MaxTriangles = 3000;
            public dVertex[] Vertex;
            public dTriangle[] Triangle;
            public int HowMany = 0;
    
            int tPoints; //Variable for total number of points (vertices)
    
            public Csharp_Delauney()
            {
                // ------------------------------------------------------------------------------------
                //Our points
                Vertex = new dVertex[MaxVertices];
                //Our Created Triangles
                Triangle = new dTriangle[MaxTriangles];
                //Initiate total points to 1, using base 0 causes problems in the functions
                tPoints = 1;
    
                // ------------------------------------------------------------------------------------
                //
                // TODO: Add any constructor code after InitializeComponent call
                //
            }
    
            public int Triangulate(ref int nvert)
            {
                // Takes as input NVERT vertices in arrays Vertex()
                // Returned is a list of NTRI triangular faces in the array
                // Triangle(). These triangles are arranged in clockwise order.
                bool[] Complete = new bool[MaxTriangles];
                int[,] Edges = new int[3, MaxTriangles * 3];
    
                int Nedge;
    
                // For Super Triangle
                double xmin;
                double xmax;
                double ymin;
                double ymax;
                double xmid;
                double ymid;
                double dx;
                double dy;
                double dmax;
    
                // General Variables
                int i;
                int j;
                int k;
                int ntri;
                bool inc;
    
                double xc;
                xc = 0;
                double yc;
                yc = 0;
                double r;
                r = 0;
    
                // Find the maximum and minimum vertex bounds.
                // This is to allow calculation of the bounding triangle
                xmin = Vertex[1].x;
                ymin = Vertex[1].y;
                xmax = xmin;
                ymax = ymin;
                for (i = 2; i <= nvert; i++)
                {
                    if (Vertex[i].x < xmin)
                    {
                        xmin = Vertex[i].x;
                    }
                    if (Vertex[i].x > xmax)
                    {
                        xmax = Vertex[i].x;
                    }
                    if (Vertex[i].y < ymin)
                    {
                        ymin = Vertex[i].y;
                    }
                    if (Vertex[i].y > ymax)
                    {
                        ymax = Vertex[i].y;
                    }
                }
    
                dx = xmax - xmin;
                dy = ymax - ymin;
                if (dx > dy)
                {
                    dmax = dx;
                }
                else
                {
                    dmax = dy;
                }
    
                xmid = (xmax + xmin) / 2;
                ymid = (ymax + ymin) / 2;
    
                // Set up the supertriangle
                // This is a triangle which encompasses all the sample points.
                // The supertriangle coordinates are added to the end of the
                // vertex list. The supertriangle is the first triangle in
                // the triangle list.
                Vertex[nvert + 1].x = (int)(xmid - 2 * dmax);
                Vertex[nvert + 1].y = (int)(ymid - dmax);
                Vertex[nvert + 2].x = (int)xmid;
                Vertex[nvert + 2].y = (int)(ymid + 2 * dmax);
                Vertex[nvert + 3].x = (int)(xmid + 2 * dmax);
                Vertex[nvert + 3].y = (int)(ymid - dmax);
                Triangle[1].vv0 = nvert + 1;
                Triangle[1].vv1 = nvert + 2;
                Triangle[1].vv2 = nvert + 3;
                Complete[1] = false;
                ntri = 1;
                // Include each point one at a time into the existing mesh
                for (i = 1; i <= nvert; i++)
                {
    
                    Nedge = 0;
                    // Set up the edge buffer.
                    // If the point (Vertex(i).x,Vertex(i).y) lies inside the circumcircle then the
                    // three edges of that triangle are added to the edge buffer.
                    j = 0;
                    do
                    {
                        j = j + 1;
                        if (Complete[j] != true)
                        {
                            inc = InCircle(ref Vertex[i].x, ref Vertex[i].y, ref Vertex[Triangle[j].vv0].x, ref Vertex[Triangle[j].vv0].y, ref Vertex[Triangle[j].vv1].x, ref Vertex[Triangle[j].vv1].y, ref Vertex[Triangle[j].vv2].x, ref Vertex[Triangle[j].vv2].y, ref xc, ref yc, ref r);
                            // Include this if points are sorted by X
                            // If (xc + r) < Vertex(i).x Then
                            // complete(j) = True
                            // Else
                            if (inc)
                            {
                                Edges[1, Nedge + 1] = Triangle[j].vv0;
                                Edges[2, Nedge + 1] = Triangle[j].vv1;
                                Edges[1, Nedge + 2] = Triangle[j].vv1;
                                Edges[2, Nedge + 2] = Triangle[j].vv2;
                                Edges[1, Nedge + 3] = Triangle[j].vv2;
                                Edges[2, Nedge + 3] = Triangle[j].vv0;
                                Nedge = Nedge + 3;
                                Triangle[j].vv0 = Triangle[ntri].vv0;
                                Triangle[j].vv1 = Triangle[ntri].vv1;
                                Triangle[j].vv2 = Triangle[ntri].vv2;
                                Complete[j] = Complete[ntri];
                                j = j - 1;
                                ntri = ntri - 1;
                            }
                        }
                    } while (j < ntri);
    
                    // Tag multiple edges
                    // Note: if all triangles are specified anticlockwise then all
                    // interior edges are opposite pointing in direction.
                    for (j = 1; j <= Nedge - 1; j++)
                    {
                        if (Edges[1, j] != 0 && Edges[2, j] != 0)
                        {
                            for (k = j + 1; k <= Nedge; k++)
                            {
                                if (Edges[1, k] != 0 && Edges[2, k] != 0)
                                {
                                    if (Edges[1, j] == Edges[2, k])
                                    {
                                        if (Edges[2, j] == Edges[1, k])
                                        {
                                            Edges[1, j] = 0;
                                            Edges[2, j] = 0;
                                            Edges[1, k] = 0;
                                            Edges[2, k] = 0;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    // Form new triangles for the current point
                    // Skipping over any tagged edges.
                    // All edges are arranged in clockwise order.
                    for (j = 1; j <= Nedge; j++)
                    {
                        if (Edges[1, j] != 0 && Edges[2, j] != 0)
                        {
                            ntri = ntri + 1;
                            Triangle[ntri].vv0 = Edges[1, j];
                            Triangle[ntri].vv1 = Edges[2, j];
                            Triangle[ntri].vv2 = i;
                            Complete[ntri] = false;
                        }
                    }
                }
                // Remove triangles with supertriangle vertices
                // These are triangles which have a vertex number greater than NVERT
                i = 0;
                do
                {
                    i = i + 1;
                    if (Triangle[i].vv0 > nvert || Triangle[i].vv1 > nvert || Triangle[i].vv2 > nvert)
                    {
                        Triangle[i].vv0 = Triangle[ntri].vv0;
                        Triangle[i].vv1 = Triangle[ntri].vv1;
                        Triangle[i].vv2 = Triangle[ntri].vv2;
                        i = i - 1;
                        ntri = ntri - 1;
                    }
                } while (i < ntri);
    
                return ntri;
    
            }
    
            private bool InCircle(ref double xp, ref double yp, ref double x1, ref double y1, ref double x2, ref double y2, ref double x3, ref double y3, ref double xc, ref double yc, ref double r)
            {
                //Return TRUE if the point (xp,yp) lies inside the circumcircle
                //made up by points (x1,y1) (x2,y2) (x3,y3)
                //The circumcircle centre is returned in (xc,yc) and the radius r
                //NOTE: A point on the edge is inside the circumcircle
                bool TheResult;
    
                double eps;
                double m1;
                double m2;
                double mx1;
                double mx2;
                double my1;
                double my2;
                double dx;
                double dy;
                double rsqr;
                double drsqr;
    
                TheResult = false;
                eps = 0.000001;
    
                if (System.Math.Abs(y1 - y2) < eps && System.Math.Abs(y2 - y3) < eps)
                {
                    //MessageBox.Show("INCIRCUM - F - Points are coincident !!");
                    TheResult = false;
                    return TheResult;
                }
    
    
                if (System.Math.Abs(y2 - y1) < eps)
                {
                    m2 = (double)-(x3 - x2) / (y3 - y2);
                    mx2 = (double)(x2 + x3) / 2;
                    my2 = (double)(y2 + y3) / 2;
                    xc = (x2 + x1) / 2;
                    yc = m2 * (xc - mx2) + my2;
                }
                else if (System.Math.Abs(y3 - y2) < eps)
                {
                    m1 = (double)-(x2 - x1) / (y2 - y1);
                    mx1 = (double)(x1 + x2) / 2;
                    my1 = (double)(y1 + y2) / 2;
                    xc = (x3 + x2) / 2;
                    yc = m1 * (xc - mx1) + my1;
                }
                else
                {
                    m1 = (double)-(x2 - x1) / (y2 - y1);
                    m2 = (double)-(x3 - x2) / (y3 - y2);
                    mx1 = (double)(x1 + x2) / 2;
                    mx2 = (double)(x2 + x3) / 2;
                    my1 = (double)(y1 + y2) / 2;
                    my2 = (double)(y2 + y3) / 2;
                    xc = (m1 * mx1 - m2 * mx2 + my2 - my1) / (m1 - m2);
                    yc = m1 * (xc - mx1) + my1;
                }
    
                dx = x2 - xc;
                dy = y2 - yc;
                rsqr = dx * dx + dy * dy;
                r = System.Math.Sqrt(rsqr);
                dx = xp - xc;
                dy = yp - yc;
                drsqr = dx * dx + dy * dy;
    
                if (drsqr <= rsqr)
                {
                    TheResult = true;
    
                }
                return TheResult;
    
            }
    
            public dVertex[] AddPoint(double x , double y)
            {
                int i;
    
                // variable to hold how many triangles are created by the triangulate function
                HowMany = 0;
    
                // Set Vertex coordinates where you clicked the pic box
                Vertex[tPoints].x = x;
                Vertex[tPoints].y = y;
    
                // Perform Triangulation Function if there are more than 2 points
                if (tPoints > 2)
                // Clear the Picture Box
                {
                    // Returns number of triangles created.
                    HowMany = Triangulate(ref tPoints);
                }
                else
                {
                    // Draw a circle where you clicked so it does something
                    // g.DrawRectangle(myPen, Vertex(tPoints).x, Vertex(tPoints).y, 14, 14)
                    //g.DrawEllipse(myPen, Vertex[tPoints].x, Vertex[tPoints].y, 4, 4);
                }
    
    
    
                // Display the total points and total triangles
                //label4.Text = "Points: " + tPoints;
                //label5.Text = "Triangles: " + HowMany;
    
                // Increment the total number of points
                tPoints = tPoints + 1;
    
                // Draw the created triangles
                for (i = 1; i <= HowMany; i++)
                {
                    //g.DrawLine(myPen, Vertex[Triangle[i].vv0].x, Vertex[Triangle[i].vv0].y, Vertex[Triangle[i].vv1].x, Vertex[Triangle[i].vv1].y);
                    //g.DrawLine(myPen, Vertex[Triangle[i].vv1].x, Vertex[Triangle[i].vv1].y, Vertex[Triangle[i].vv2].x, Vertex[Triangle[i].vv2].y);
                    //g.DrawLine(myPen, Vertex[Triangle[i].vv0].x, Vertex[Triangle[i].vv0].y, Vertex[Triangle[i].vv2].x, Vertex[Triangle[i].vv2].y);
                }
                return Vertex;
    
            }
    
            public dVertex[] GetDVertices()
            {
                return Vertex;
            }
            public dTriangle[] GetDTriangles()
            {
                return Triangle;
            }
        }
    }
    -----------------------------
    调用
    Csharp_Delauney csharp_Delauney = new Csharp_Delauney();
                        foreach (var entity in pionts)
                        {
                            if (entity is Point3d)
                            {
                                var piont = (Point3d)entity;
                                var newpiont = new Point3d(piont.X, piont.Y + 1000, piont.Z);
                                csharp_Delauney.AddPoint(newpiont.X, newpiont.Y);
                            }
                        }
                        var dVertices = csharp_Delauney.GetDVertices();
                        var dTriangles = csharp_Delauney.GetDTriangles();
                        var HowMany = csharp_Delauney.HowMany;
                        db.SetCurrentLayer(db.GetLayer("轮廓线"));
                        DBObjectCollection tdBObjectCollectionLine = new DBObjectCollection();//画地形
                        for (var i = 1; i <= HowMany; i++)
                        {
                            //  g.DrawLine(myPen, Vertex[Triangle[i].vv0].x, Vertex[Triangle[i].vv0].y, Vertex[Triangle[i].vv1].x, Vertex[Triangle[i].vv1].y);
                            var ptA1 = new Point3d(dVertices[dTriangles[i].vv0].x, dVertices[dTriangles[i].vv0].y, 0);
                            var ptA2 = new Point3d(dVertices[dTriangles[i].vv1].x, dVertices[dTriangles[i].vv1].y, 0);
                            var aLine = ptA1.Line(ptA2);
                            tdBObjectCollectionLine.Add(aLine);
                            // g.DrawLine(myPen, Vertex[Triangle[i].vv1].x, Vertex[Triangle[i].vv1].y, Vertex[Triangle[i].vv2].x, Vertex[Triangle[i].vv2].y);
                            var ptB1 = new Point3d(dVertices[dTriangles[i].vv1].x, dVertices[dTriangles[i].vv1].y, 0);
                            var ptB2 = new Point3d(dVertices[dTriangles[i].vv2].x, dVertices[dTriangles[i].vv2].y, 0);
                            var bLine = ptB1.Line(ptB2);
                            tdBObjectCollectionLine.Add(bLine);
                            // g.DrawLine(myPen, Vertex[Triangle[i].vv0].x, Vertex[Triangle[i].vv0].y, Vertex[Triangle[i].vv2].x, Vertex[Triangle[i].vv2].y);
                            var ptC1 = new Point3d(dVertices[dTriangles[i].vv0].x, dVertices[dTriangles[i].vv0].y, 0);
                            var ptC2 = new Point3d(dVertices[dTriangles[i].vv2].x, dVertices[dTriangles[i].vv2].y, 0);
                            var cLine = ptC1.Line(ptC2);
                            tdBObjectCollectionLine.Add(cLine);
                        }
    
                        db.AddObjectsToModelSpace(tdBObjectCollectionLine);

    代码

    https://download.csdn.net/download/bosslizhiyong/21454486

     
  • 相关阅读:
    推荐系统学习--cb+cf 初见
    耳机的阻抗和灵敏度问题
    java中常见的几种Runtimeexception
    java泛型
    ubuntu安装opencv
    ubuntu12.04静态ip设置问题
    Graph Theory
    SQL简单上手教程
    C++ 构造函数、拷贝构造函数和赋值运算符重载
    C语言函数调用栈
  • 原文地址:https://www.cnblogs.com/shangdishijiao/p/15175316.html
Copyright © 2011-2022 走看看