예제 #1
0
        /// <summary>
        /// Verifica se la faccia è convessa. Un poligono semplice è strettamente convesso se ogni
        /// angolo interno è strettamente inferiore a 180 gradi.
        /// </summary>
        /// <returns>True se la faccia è convessa, false altrimenti.</returns>
        public bool IsConvex()
        {
            DCELHalfEdge he    = this.Edge;
            DCELHalfEdge prev  = he.Previous();
            DCELVertex   first = he.Origin;

            do
            {
                Vector3D v1 = new Vector3D(
                    prev.Origin.Coordinates.X - he.Origin.Coordinates.X,
                    prev.Origin.Coordinates.Y - he.Origin.Coordinates.Y,
                    prev.Origin.Coordinates.Z - he.Origin.Coordinates.Z);

                Vector3D v2 = new Vector3D(
                    he.Next.Origin.Coordinates.X - he.Origin.Coordinates.X,
                    he.Next.Origin.Coordinates.Y - he.Origin.Coordinates.Y,
                    he.Next.Origin.Coordinates.Z - he.Origin.Coordinates.Z);

                double dotProduct = (v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z);
                double norm1      = Math.Sqrt(Math.Pow(v1.X, 2) + Math.Pow(v1.Y, 2) + Math.Pow(v1.Z, 2));
                double norm2      = Math.Sqrt(Math.Pow(v2.X, 2) + Math.Pow(v2.Y, 2) + Math.Pow(v2.Z, 2));
                double angle      = (Math.Acos(dotProduct / (norm1 * norm2)) * 180) / Math.PI;

                if (angle > 180)
                {
                    return(false);
                }

                prev = he;
                he   = he.Next;
            }while (he.Origin != first);

            //returns true if every internal angle is less than or equal to 180 degrees
            return(true);
        }
예제 #2
0
 public DCELHalfEdge(DCELVertex origin, DCELFace face, DCELHalfEdge twin, DCELHalfEdge next)
 {
     Origin = origin;
     Face   = face;
     Twin   = twin;
     Next   = next;
 }
예제 #3
0
        public bool AddVertex(DCELVertex vertex)
        {
            vertexList.Add(vertex);
            vertexCount++;

            return(true);
        }
예제 #4
0
 public bool RemoveVertex(DCELVertex vertex)
 {
     if (vertexList.Remove(vertex))
     {
         vertexCount--;
         return(true);
     }
     return(false);
 }
예제 #5
0
        /// <summary>
        /// Restituisce i lati della faccia.
        /// </summary>
        /// <returns>DCELHalfEdge collection.</returns>
        public IEnumerable <DCELHalfEdge> Sides()
        {
            DCELHalfEdge he    = this.Edge;
            DCELVertex   first = he.Origin;

            do
            {
                yield return(he);

                he = he.Next;
            }while (he.Origin != first);
        }
예제 #6
0
        /// <summary>
        /// Restituisce tutte le facce confinanti.
        /// </summary>
        /// <returns>DCELFace collection.</returns>
        public IEnumerable <DCELFace> Neighbours()
        {
            DCELHalfEdge he    = this.Edge;
            DCELVertex   first = he.Origin;

            do
            {
                if (!he.Twin.Face.IsInfinite())
                {
                    yield return(he.Twin.Face);
                }
                he = he.Next;
            }while (he.Origin != first);
        }
예제 #7
0
        public bool TriangulateFace(DCELFace face)
        {
            //lista di appoggio
            List <DCELHalfEdge> edges = face.Sides().ToList();
            //sides è il numero di lati della faccia
            int sides = edges.Count;
            //first è il vertice a partire dal quale viene suddiviso il poligono
            DCELVertex first = edges[0].Origin;

            //se la faccia non esiste o se esiste ma ha meno di 4 lati o non è convessa restituisco false
            //if (sides <= 3 || !this.Contains(face) || !face.IsConvex())
            //    return false;

            for (int i = 0; i < sides; i++)
            {
                if (i == 0)
                {
                    this.AddFace(new DCELFace(edges[i], face.Normal));
                    edges[i].Face = faceList[FaceCount - 1];
                    i++;
                    edges[i].Face = faceList[FaceCount - 1];
                    this.AddHalfEdge(new DCELHalfEdge(edges[i].Next.Origin, faceList[FaceCount - 1], null, edges[0]));
                    edges[i].Next = edgeList[HalfEdgeCount - 1];
                }
                else if (i == sides - 2)
                {
                    this.AddFace(new DCELFace(null, face.Normal));
                    this.AddHalfEdge(new DCELHalfEdge(first, faceList[FaceCount - 1], edgeList[HalfEdgeCount - 1], edges[i]));
                    edges[i].Face = faceList[FaceCount - 1];
                    i++;
                    edges[i].Face = faceList[FaceCount - 1];
                    edgeList[HalfEdgeCount - 2].Twin = edgeList[HalfEdgeCount - 1];
                    faceList[FaceCount - 1].Edge     = edgeList[HalfEdgeCount - 1];
                    edges[i].Next = edgeList[HalfEdgeCount - 1];
                }
                else
                {
                    this.AddFace(new DCELFace(null, face.Normal));
                    this.AddHalfEdge(new DCELHalfEdge(first, faceList[FaceCount - 1], edgeList[HalfEdgeCount - 1], edges[i]));
                    faceList[FaceCount - 1].Edge = edgeList[HalfEdgeCount - 1];
                    edges[i].Face = faceList[FaceCount - 1];
                    edgeList[HalfEdgeCount - 2].Twin = edgeList[HalfEdgeCount - 1];
                    this.AddHalfEdge(new DCELHalfEdge(edges[i].Next.Origin, faceList[faceCount - 1], null, edgeList[HalfEdgeCount - 1]));
                    edges[i].Next = edgeList[HalfEdgeCount - 1];
                }
            }
            //ora è possibile rimuovere la faccia dalla lista
            return(RemoveFace(face));
        }
예제 #8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="mesh"></param>
        /// <returns></returns>
        public static MeshGeometry3D GetMeshGeometry(DCELMesh mesh)
        {
            MeshGeometry3D mesh3d   = new MeshGeometry3D();
            Hashtable      vIndexes = new Hashtable();
            int            n        = 0;

            mesh.Triangulate();

            foreach (var point3d in mesh.VertexList)
            {
                mesh3d.Positions.Add(point3d.Coordinates);
                mesh3d.Normals.Add(point3d.Normal);
                vIndexes.Add(point3d, n++);
            }

            foreach (var face in mesh.FaceList)
            {
                DCELHalfEdge he    = face.Edge;
                DCELVertex   first = he.Origin;

                do
                {
                    mesh3d.TriangleIndices.Add((int)vIndexes[he.Origin]);
                    he = he.Next;
                }while (he.Origin != first);
            }

            /*
             * foreach (var face in mesh.FaceList)
             * {
             *  DCELHalfEdge he = face.Edge;
             *  DCELVertex first = he.Origin;
             *
             *  do
             *  {
             *      mesh3d.Positions.Add(he.Origin.Coordinates);
             *      mesh3d.Normals.Add(he.Origin.Normal);
             *      mesh3d.TriangleIndices.Add(n++);
             *      he = he.Next;
             *  }
             *  while (he.Origin != first);
             * }
             */
            return(mesh3d);
        }
예제 #9
0
 public bool Contains(DCELVertex vertex)
 {
     return(vertexList.Contains(vertex));
 }