Exemple #1
0
 /// <summary>
 /// using a DFS to find the horizon
 /// </summary>
 /// <param name="f">root of the DFS</param>
 /// <param name="v">the vertex to be computed</param>
 private void ComputeHorizon(TriangularFace f, DualSite v)
 {
     f.Valid = false;
     DFSProcess(f.Edge0, v);
     DFSProcess(f.Edge1, v);
     DFSProcess(f.Edge2, v);
 }
Exemple #2
0
        /// <summary>
        /// Compute the convex hull in 3-D space
        /// </summary>
        /// <returns>surfaces of the convex hull</returns>
        public List <TriangularFace> Compute()
        {
            NumFace = 0;
            if (NumVertex < 4)
            {
                return(null);
            }

            Prepare();

            for (int i = 4; i < NumVertex; i++)
            {
                for (int j = 0; j < NumFace; j++)
                {
                    if (HullFace[j].Valid && HullFace[j].VOutFace(Vertices[i]))
                    {
                        Horizon.Clear();
                        ComputeHorizon(HullFace[j], Vertices[i]);
                        SortHorizons();

                        TriangularFace first = null;
                        TriangularFace last  = null;
                        DualSite       v     = Vertices[i];
                        for (int ii = 0; ii < Horizon.Count; ii++)
                        {
                            Edge           e   = Horizon[ii];
                            TriangularFace f   = e.NeighborFace;
                            TriangularFace add = new TriangularFace(e.Vertex0, e.Vertex1, v);
                            HullFace.Add(add);
                            NumFace++;
                            f.SetNeighbor(add, e.Vertex0, e.Vertex1);
                            if (first == null)
                            {
                                first = add;
                            }
                            else
                            {
                                add.SetNeighbor(last, e.Vertex0, v);
                            }
                            last = add;
                        }

                        last.SetNeighbor(first, last.Edge0.Vertex1, Vertices[i]);
                        break;
                    }
                }
            }

            List <TriangularFace> result = new List <TriangularFace>();

            for (int i = 0; i < HullFace.Count; i++)
            {
                if (HullFace[i].Valid)
                {
                    result.Add(HullFace[i]);
                }
            }
            return(result);
        }
Exemple #3
0
        /// <summary>
        /// let the first three vertices noncollinear and the first four vertices noncoplanar
        /// </summary>
        private void Prepare()
        {
            Vector3D tmp_vector = new Vector3D();

            for (int i = 2; i < NumVertex; i++)
            {
                tmp_vector = Vector3D.CrossProduct(Vertices[1].Coordinate - Vertices[0].Coordinate, Vertices[i].Coordinate - Vertices[0].Coordinate);
                if (tmp_vector.LengthSquared > Eps)//三点不共线
                {
                    if (i != 2)
                    {
                        DualSite tmp = Vertices[i];
                        Vertices[i] = Vertices[2];
                        Vertices[2] = tmp;
                    }
                    break;
                }
            }

            for (int i = 3; i < NumVertex; i++)
            {
                if (Math.Abs(Vector3D.DotProduct(tmp_vector, Vertices[i].Coordinate - Vertices[0].Coordinate)) > Eps)//四点不共面
                {
                    if (i != 3)
                    {
                        DualSite tmp = Vertices[i];
                        Vertices[i] = Vertices[3];
                        Vertices[3] = tmp;
                    }
                    break;
                }
            }

            //为使面法向量方向指向凸包外
            TriangularFace tmp_face = new TriangularFace(Vertices[0], Vertices[1], Vertices[2]);

            if (tmp_face.VOutFace(Vertices[3]))
            {
                DualSite tmp = Vertices[2];
                Vertices[2] = Vertices[3];
                Vertices[3] = tmp;
            }
            HullFace.Add(new TriangularFace(Vertices[0], Vertices[1], Vertices[2]));
            HullFace.Add(new TriangularFace(Vertices[1], Vertices[3], Vertices[2]));
            HullFace.Add(new TriangularFace(Vertices[0], Vertices[2], Vertices[3]));
            HullFace.Add(new TriangularFace(Vertices[0], Vertices[3], Vertices[1]));

            HullFace[0].SetNeighbor(HullFace[1], Vertices[1], Vertices[2]);
            HullFace[0].SetNeighbor(HullFace[2], Vertices[0], Vertices[2]);
            HullFace[0].SetNeighbor(HullFace[3], Vertices[0], Vertices[1]);
            HullFace[1].SetNeighbor(HullFace[2], Vertices[2], Vertices[3]);
            HullFace[1].SetNeighbor(HullFace[3], Vertices[1], Vertices[3]);
            HullFace[2].SetNeighbor(HullFace[3], Vertices[0], Vertices[3]);

            NumFace = 4;
        }
        private void ComputeData()
        {
            foreach (TriangularFace f in HullFaces)
            {
                if (f.Normal.Z < -Eps)
                {
                    List <Edge> edges = new List <Edge>();
                    edges.Add(f.Edge0);
                    edges.Add(f.Edge1);
                    edges.Add(f.Edge2);

                    foreach (Edge e in edges)
                    {
                        DualSite dest = e.Vertex0;
                        if (!dest.Visited)
                        {
                            dest.OriginalSite.NeighborSites = new List <Site>();
                            Site site = dest.OriginalSite;
                            dest.Visited = true;
                            if (site.IsDummy())
                            {
                                continue;
                            }

                            List <TriangularFace> tmp_faces = GetNeighborface(e);
                            site.Polyon = new Polygon();

                            foreach (TriangularFace face in tmp_faces)
                            {
                                Vector point = face.GetDualPoint();
                                site.Polyon.Add(point);
                            }

                            if (!site.IsDummy())
                            {
                                //@site.polyon
                                //@BoundPoly
                                ConvexIntersect clippoly = new ConvexIntersect(site.Polyon, BoundPoly);
                                site.ClipPolyon = clippoly.Compute();
                                if (site.ClipPolyon.Count == 0)
                                {
                                    site.ClipPolyon = site.Polyon;
                                }
                            }
                        }
                    }
                }
            }
        }
Exemple #5
0
        private void DFSProcess(Edge e, DualSite v)
        {
            TriangularFace f = e.NeighborFace;

            if (f.Valid)
            {
                if (f.VOutFace(v))
                {
                    ComputeHorizon(f, v);
                }
                else
                {
                    Horizon.Add(e);
                }
            }
        }