Ejemplo n.º 1
0
        private void MainLoop()
        {
            int count = 0;

            while (faceQueue.Count > 0)
            {
                count++;
                HullFace face = faceQueue.Dequeue();

                if (face.active == false)
                {
                    continue;
                }

                if (face.furthestIndex != -1)
                {
                    int p0 = face.furthestIndex;

                    this.hullVertices.Add(p0);

                    // collect visible faces, boundary edges and assoicated vertices
                    List <HullFace>      holeFace         = new List <HullFace>();
                    HashSet <EdgeRecord> holeBoundary     = new HashSet <EdgeRecord>();
                    HashSet <int>        assoicatedVertex = new HashSet <int>();
                    foreach (HullFace f in this.surfaceSet)
                    {
                        Vector3d v = this.p[p0] - this.p[f.p1];
                        if (v.Dot(f.normal) > 0)
                        {
                            holeFace.Add(f);

                            int        p1 = f.p1;
                            int        p2 = f.p2;
                            int        p3 = f.p3;
                            EdgeRecord r1 = new EdgeRecord(p1, p2);
                            EdgeRecord r2 = new EdgeRecord(p2, p3);
                            EdgeRecord r3 = new EdgeRecord(p3, p1);
                            if (holeBoundary.Contains(r1))
                            {
                                holeBoundary.Remove(r1);
                            }
                            else
                            {
                                holeBoundary.Add(r1);
                            }
                            if (holeBoundary.Contains(r2))
                            {
                                holeBoundary.Remove(r2);
                            }
                            else
                            {
                                holeBoundary.Add(r2);
                            }
                            if (holeBoundary.Contains(r3))
                            {
                                holeBoundary.Remove(r3);
                            }
                            else
                            {
                                holeBoundary.Add(r3);
                            }

                            foreach (int index in f.associatedPoints)
                            {
                                assoicatedVertex.Add(index);
                            }
                        }
                    }
                    if (holeFace.Count == 0)
                    {
                        throw new Exception();
                    }

                    // remove add visible faces
                    foreach (HullFace f in holeFace)
                    {
                        this.surfaceSet.Remove(f);
                        f.active = false;
                    }

                    // add new faces
                    foreach (EdgeRecord edge in holeBoundary)
                    {
                        HullFace newFace = new HullFace(p0, edge.p1, edge.p2);
                        newFace.normal = ((p[edge.p1] - p[p0]).Cross(p[edge.p2] - p[p0])).normalize();
                        this.surfaceSet.Add(newFace);
                        this.faceQueue.Enqueue(newFace);

                        // add assoicated vertices
                        foreach (int index in assoicatedVertex)
                        {
                            if (index == p0)
                            {
                                continue;
                            }

                            double dis = (p[index] - p[p0]).Dot(newFace.normal);
                            if (dis > 0)
                            {
                                newFace.AddPoint(index, dis);
                            }
                        }
                    }
                }
            }
            computeCenter();
        }
Ejemplo n.º 2
0
        private void InitHullFaces()
        {
            // get init points
            int[] initPts = FindInitPoints();
            this.initIndex = initPts;
            int    p0  = initPts[0];
            int    p1  = initPts[1];
            int    p2  = initPts[2];
            int    p3  = initPts[3];
            double vol = (p[p1] - p[p0]).Dot((p[p2] - p[p0]).Cross(p[p3] - p[p0]));

            if (vol > 0)
            {
                int t = p0; p0 = p1; p1 = t;
            }
            this.hullVertices.Add(p0);
            this.hullVertices.Add(p1);
            this.hullVertices.Add(p2);
            this.hullVertices.Add(p3);

            // create hull faces
            HullFace f1 = new HullFace(p0, p1, p2); this.faceQueue.Enqueue(f1);
            HullFace f2 = new HullFace(p3, p1, p0); this.faceQueue.Enqueue(f2);
            HullFace f3 = new HullFace(p3, p2, p1); this.faceQueue.Enqueue(f3);
            HullFace f4 = new HullFace(p3, p0, p2); this.faceQueue.Enqueue(f4);

            f1.normal = ((p[p1] - p[p0]).Cross(p[p2] - p[p0])).normalize();
            f2.normal = ((p[p1] - p[p3]).Cross(p[p0] - p[p3])).normalize();
            f3.normal = ((p[p2] - p[p3]).Cross(p[p1] - p[p3])).normalize();
            f4.normal = ((p[p0] - p[p3]).Cross(p[p2] - p[p3])).normalize();
            this.surfaceSet.Add(f1);
            this.surfaceSet.Add(f2);
            this.surfaceSet.Add(f3);
            this.surfaceSet.Add(f4);
            // assoicate vertices outside current hull
            foreach (int i in this.pointIndex)
            {
                if (i == p0 || i == p1 || i == p2 || i == p3)
                {
                    continue;
                }
                double d1 = (p[i] - p[p0]).Dot(f1.normal);
                double d2 = (p[i] - p[p3]).Dot(f2.normal);
                double d3 = (p[i] - p[p3]).Dot(f3.normal);
                double d4 = (p[i] - p[p3]).Dot(f4.normal);
                if (d1 < 0 && d2 < 0 && d3 < 0 && d4 < 0)
                {
                    continue;
                }
                if (d1 > 0)
                {
                    f1.AddPoint(i, d1);
                }
                if (d2 > 0)
                {
                    f2.AddPoint(i, d2);
                }
                if (d3 > 0)
                {
                    f3.AddPoint(i, d3);
                }
                if (d4 > 0)
                {
                    f4.AddPoint(i, d4);
                }
            }
        }