Пример #1
0
 public void InitHead(cFace h)
 {
     head      = new cFace();
     head      = h;
     head.next = head.prev = head;
     n         = 1;
 }
Пример #2
0
        /*---------------------------------------------------------------------
        *  Computes the z-coordinate of the vector normal to face f.
        *  ---------------------------------------------------------------------*/
        private double Normz(cFace f)
        {
            cVertex a, b, c;

            /*double ba0, ca1, ba1, ca0,z;*/

            a = f.Vertices[0];
            b = f.Vertices[1];
            c = f.Vertices[2];

            /*
             * ba0 = ( b.v.x - a.v.x );
             * ca1 = ( c.v.y - a.v.y );
             * ba1 = ( b.v.y - a.v.y );
             * ca0 = ( c.v.x - a.v.x );
             *
             * z = ba0 * ca1 - ba1 * ca0;
             * System.Diagnostics.Debug.WriteLine("Normz = %lf=%g\n", z,z);
             * if      ( z > 0.0 )  return  1;
             * else if ( z < 0.0 )  return -1;
             * else                 return  0;
             */
            return
                ((b.Point.X - a.Point.X) * (c.Point.Y - a.Point.Y) -
                 (b.Point.Y - a.Point.Y) * (c.Point.X - a.Point.X));
        }
Пример #3
0
        private void LowerFaces()
        {
            cFace f = Faces.head;
            /*int   z;*/
            int Flower = 0;   /* Total number of lower faces. */

            do
            {
                /*z = Normz( f );
                 * if ( z < 0 ) {*/
                if (Normz(f) < 0)
                {
                    Flower++;
                    f.lower = true;
                    System.Diagnostics.Debug.WriteLine("lower face indices: " + f.Vertices[0].IndexInPointCloud + ", " +
                                                       f.Vertices[1].IndexInPointCloud + ", " + f.Vertices[2].IndexInPointCloud);
                }
                else
                {
                    f.lower = false;
                }
                f = f.next;
            } while (f != Faces.head);
            System.Diagnostics.Debug.WriteLine("A total of " + Flower + " lower faces identified.");
        }
Пример #4
0
        /*---------------------------------------------------------------------
        *  Volumed is the same as VolumeSign but computed with doubles.  For
        *  protection against overflow.
        *  ---------------------------------------------------------------------*/
        private double Volumed(cFace f, cVertex p)
        {
            double vol;
            double ax, ay, az, bx, by, bz, cx, cy, cz, dx, dy, dz;
            double bxdx, bydy, bzdz, cxdx, cydy, czdz;

            ax = f.Vertices[0].Point.X;
            ay = f.Vertices[0].Point.Y;
            az = f.Vertices[0].Point.Z;
            bx = f.Vertices[1].Point.X;
            by = f.Vertices[1].Point.Y;
            bz = f.Vertices[1].Point.Z;
            cx = f.Vertices[2].Point.X;
            cy = f.Vertices[2].Point.Y;
            cz = f.Vertices[2].Point.Z;
            dx = p.Point.X;
            dy = p.Point.Y;
            dz = p.Point.Z;

            bxdx = bx - dx;
            bydy = by - dy;
            bzdz = bz - dz;
            cxdx = cx - dx;
            cydy = cy - dy;
            czdz = cz - dz;
            vol  = (az - dz) * (bxdx * cydy - bydy * cxdx)
                   + (ay - dy) * (bzdz * cxdx - bxdx * czdz)
                   + (ax - dx) * (bydy * czdz - bzdz * cydy);

            return(vol);
        }
Пример #5
0
        /*---------------------------------------------------------------------
        *  MakeFace creates a new face structure from three pointCloud (in ccw
        *  order).  It returns a pointer to the face.
        *  ---------------------------------------------------------------------*/
        private cFace MakeFace(cVertex v0, cVertex v1, cVertex v2, cFace fold)
        {
            cFace f;
            cEdge e0, e1, e2;

            /* Create edges of the initial triangle. */
            if (fold == null)
            {
                e0 = Edges.MakeNullEdge();
                e1 = Edges.MakeNullEdge();
                e2 = Edges.MakeNullEdge();
            }
            else
            { /* Copy from fold, in reverse order. */
                e0 = fold.Edges[2];
                e1 = fold.Edges[1];
                e2 = fold.Edges[0];
            }
            e0.Endpts[0] = v0; e0.Endpts[1] = v1;
            e1.Endpts[0] = v1; e1.Endpts[1] = v2;
            e2.Endpts[0] = v2; e2.Endpts[1] = v0;

            /* Create face for triangle. */
            f             = Faces.MakeNullFace();
            f.Edges[0]    = e0; f.Edges[1] = e1; f.Edges[2] = e2;
            f.Vertices[0] = v0; f.Vertices[1] = v1; f.Vertices[2] = v2;

            /* Link edges to face. */
            e0.Adjface[0] = e1.Adjface[0] = e2.Adjface[0] = f;

            return(f);
        }
Пример #6
0
        public cFace MakeNullFace()
        {
            cFace f = new cFace();

            InsertBeforeHead(f);
            return(f);
        }
Пример #7
0
        /*---------------------------------------------------------------------*/
        protected float Volumei(cFace f, cVertex p)
        {
            float vol;
            float ax, ay, az, bx, by, bz, cx, cy, cz, dx, dy, dz;
            float bxdx, bydy, bzdz, cxdx, cydy, czdz;

            //float vold;
            //int i;

            ax = f.Vertices[0].Point.X;
            ay = f.Vertices[0].Point.Y;
            az = f.Vertices[0].Point.Z;
            bx = f.Vertices[1].Point.X;
            by = f.Vertices[1].Point.Y;
            bz = f.Vertices[1].Point.Z;
            cx = f.Vertices[2].Point.X;
            cy = f.Vertices[2].Point.Y;
            cz = f.Vertices[2].Point.Z;
            dx = p.Point.X;
            dy = p.Point.Y;
            dz = p.Point.Z;

            bxdx = bx - dx;
            bydy = by - dy;
            bzdz = bz - dz;
            cxdx = cx - dx;
            cydy = cy - dy;
            czdz = cz - dz;
            vol  = (az - dz) * (bxdx * cydy - bydy * cxdx)
                   + (ay - dy) * (bzdz * cxdx - bxdx * czdz)
                   + (ax - dx) * (bydy * czdz - bzdz * cydy);

            return(vol);
        }
Пример #8
0
 public void ClearFaceList()
 {
     if (head != null)
     {
         head = null;
     }
     n = 0;
 }
Пример #9
0
 public cFace()
 {
     Edges       = new cEdge[3];
     Edges[0]    = Edges[1] = Edges[2] = null;
     Vertices    = new cVertex[3];
     Vertices[0] = Vertices[1] = Vertices[2] = null;
     visible     = lower = false;
     next        = prev = null;
 }
Пример #10
0
        /*---------------------------------------------------------------------
        *  doubleTriangle builds the initial double triangle.  It first finds 3
        *  noncollinear points and makes two faces out of them, in opposite order.
        *  It then finds a fourth point that is not coplanar with that face.  The
        *  pointCloud are stored in the face structure in counterclockwise order so
        *  that the volume between the face and the point is negative. Lastly, the
        *  3 newfaces to the fourth point are constructed and the data structures
        *  are cleaned up.
        *  ---------------------------------------------------------------------*/
        private bool doubleTriangle()
        {
            cVertex v0, v1, v2, v3;//;, t;
            cFace   f0, f1 = null;

            double vol;


            /* Find 3 non-Collinear points. */
            v0 = Vertices.head;
            while (Collinear(v0, v0.NextVertex, v0.NextVertex.NextVertex))
            {
                if ((v0 = v0.NextVertex) == Vertices.head)
                {
                    System.Diagnostics.Debug.WriteLine("doubleTriangle:  All points are Collinear!");
                    return(false);
                }
            }
            v1 = v0.NextVertex;
            v2 = v1.NextVertex;

            /* Mark the pointCloud as processed. */
            v0.IsProcessed = PROCESSED;
            v1.IsProcessed = PROCESSED;
            v2.IsProcessed = PROCESSED;

            /* Create the two "twin" faces. */
            f0 = MakeFace(v0, v1, v2, f1);
            f1 = MakeFace(v2, v1, v0, f0);

            /* Link adjacent face fields. */
            f0.Edges[0].Adjface[1] = f1;
            f0.Edges[1].Adjface[1] = f1;
            f0.Edges[2].Adjface[1] = f1;
            f1.Edges[0].Adjface[1] = f0;
            f1.Edges[1].Adjface[1] = f0;
            f1.Edges[2].Adjface[1] = f0;

            /* Find a fourth, non-coplanar point to form tetrahedron. */
            v3  = v2.NextVertex;
            vol = VolumeSign(f0, v3);
            while (vol == 0)
            {
                if ((v3 = v3.NextVertex) == v0)
                {
                    System.Diagnostics.Debug.WriteLine("doubleTriangle:  All points are coplanar!");
                    return(false);
                }
                vol = VolumeSign(f0, v3);
            }

            /* Insure that v3 will be the first added. */
            Vertices.head = v3;

            return(true);
        }
Пример #11
0
        public cEdge next, prev;       /* pointers to neighbours in cEdgeList */

        public cEdge()
        {
            Adjface    = new cFace[2];
            Adjface[0] = Adjface[1] = null;
            Endpts     = new cVertex[2];
            Endpts[0]  = Endpts[1] = null;
            newface    = null;
            delete     = false;
            next       = prev = null;
        }
Пример #12
0
 /*Inserts newF before oldF
  */
 public void InsertBeforeHead(cFace e)
 {
     if (head == null)
     {
         InitHead(e);
     }
     else
     {
         InsertBefore(e, head);
     }
 }
Пример #13
0
        public void PrintFaces()
        {
            cFace temp = head;
            int   i    = 1;

            if (head != null)
            {
                do
                {
                    temp.PrintFace(i);
                    temp = temp.next;
                    i++;
                } while (temp != head);
            }
        }
Пример #14
0
        public void Delete(cFace e)
        {
            if (head == head.next)
            {
                head = null;
            }
            else if (e == head)
            {
                head = head.next;
            }

            e.prev.next = e.next;
            e.next.prev = e.prev;
            n--;
        }
Пример #15
0
 public void InsertBefore(cFace newF, cFace oldF)
 {
     if (head == null)
     {
         InitHead(newF);
     }
     else
     {
         oldF.prev.next = newF;
         newF.prev      = oldF.prev;
         newF.next      = oldF;
         oldF.prev      = newF;
         n++;
     }
 }
Пример #16
0
        public bool Voronoi(List <Vector3> myListVectors)
        {
            if (Delaunay(myListVectors))
            {
                for (int i = 0; i < this.Faces.ListFaces.Count; i++)
                {
                    cFace face = this.Faces.ListFaces[i];
                    for (int j = 0; j < face.Edges.Length; j++)
                    {
                        cEdge edge = face.Edges[j];
                        for (int k = 0; k < edge.Adjface.Length; k++)
                        {
                            cFace adjFace = edge.Adjface[k];
                            cEdge newEdge = new cEdge();

                            //Kante m durch Verbindung der Umkreismittelpunkte von k und k+1
                        }
                    }
                }
                return(true);
            }
            return(false);

            //var t = DelaunayTriangulation<TCell>.Create(data);
            //var myCells = t.Cells;
            //var edges = new HashSet<TEdge>(new EdgeComparer());

            //foreach (var c in myCells)
            //{
            //    for (int i = 0; i < c.Adjacency.Length; i++)
            //    {
            //        var af = c.Adjacency[i];
            //        if (af != null)
            //            edges.Add(new TEdge { Source = c, Target = af });
            //    }
            //}

            //return new VoronoiMesh<TCell, TEdge>
            //{
            //    Cells = myCells,
            //    Edges = edges.ToList()
            //};
        }
Пример #17
0
        /*---------------------------------------------------------------------
        *  MakeCcw puts the pointCloud in the face structure in counterclock wise
        *  order.  We want to store the pointCloud in the same
        *  order as in the visible face.  The third vertex is always p.
        *  ---------------------------------------------------------------------*/
        private void MakeCcw(cFace f, cEdge e, cVertex p)
        {
            cFace fv;                /* The visible face adjacent to e */
            int   i;                 /* Index of e.endpoint[0] in fv. */
            cEdge s = new cEdge();   /* Temporary, for swapping */

            if (e.Adjface[0].visible)
            {
                fv = e.Adjface[0];
            }
            else
            {
                fv = e.Adjface[1];
            }

            /* Set vertex[0] & [1] of f to have the same orientation
             * as do the corresponding pointCloud of fv. */
            for (i = 0; fv.Vertices[i] != e.Endpts[0]; ++i)
            {
                ;
            }
            /* Orient f the same as fv. */
            if (fv.Vertices[(i + 1) % 3] != e.Endpts[1])
            {
                f.Vertices[0] = e.Endpts[1];
                f.Vertices[1] = e.Endpts[0];
            }
            else
            {
                f.Vertices[0] = e.Endpts[0];
                f.Vertices[1] = e.Endpts[1];
                Swap(s, f.Edges[1], f.Edges[2]);
            }

            /* This swap is tricky. e is edge[0]. edge[1] is based on endpt[0],
             * edge[2] on endpt[1].  So if e is oriented "forwards," we
             * need to move edge[1] to follow [0], because it precedes. */

            f.Vertices[2] = p;
        }
Пример #18
0
        /*---------------------------------------------------------------------
        *  VolumeSign returns the sign of the volume of the tetrahedron determined
        *  by f and p.  VolumeSign is +1 iff p is on the negative side of f,
        *  where the positive side is determined by the rh-rule.  So the volume
        *  is positive if the ccw normal to f points outside the tetrahedron.
        *  The  fewer-multiplications form is due to Robert Fraczkiewicz.
        *  ---------------------------------------------------------------------*/
        private double VolumeSign(cFace f, cVertex p)
        {
            double vol;
            //double voli = 0;
            double ax, ay, az, bx, by, bz, cx, cy, cz, dx, dy, dz;
            double bxdx, bydy, bzdz, cxdx, cydy, czdz;

            ax = f.Vertices[0].Point.X;
            ay = f.Vertices[0].Point.Y;
            az = f.Vertices[0].Point.Z;
            bx = f.Vertices[1].Point.X;
            by = f.Vertices[1].Point.Y;
            bz = f.Vertices[1].Point.Z;
            cx = f.Vertices[2].Point.X;
            cy = f.Vertices[2].Point.Y;
            cz = f.Vertices[2].Point.Z;
            dx = p.Point.X;
            dy = p.Point.Y;
            dz = p.Point.Z;

            bxdx = bx - dx;
            bydy = by - dy;
            bzdz = bz - dz;
            cxdx = cx - dx;
            cydy = cy - dy;
            czdz = cz - dz;
            vol  = (az - dz) * (bxdx * cydy - bydy * cxdx)
                   + (ay - dy) * (bzdz * cxdx - bxdx * czdz)
                   + (ax - dx) * (bydy * czdz - bzdz * cydy);


            return(vol);

            ///* The volume should be an integer. */
            //if (vol > 0) return 1;
            //else if (vol < 0) return -1;
            //else return 0;
        }
Пример #19
0
 public cFaceList()
 {
     head = null;
     n    = 0;
 }