Пример #1
0
        /// <summary>
        /// Merges a point to a convex hull that is a line segment.
        /// </summary>
        /// <param name="point">The point.</param>
        private void GrowLinearConvex(Vector3F point)
        {
            Debug.Assert(_mesh != null);
              Debug.Assert(_mesh.Vertices.Count == 2, "DCEL mesh with 2 vertices was expected.");
              Debug.Assert(_type == ConvexHullType.Linear);
              Debug.Assert(!Vector3F.AreNumericallyEqual(_mesh.Vertex.Position, point));
              Debug.Assert(!Vector3F.AreNumericallyEqual(_mesh.Vertices[1].Position, point));

              // Abort if the point is equal to an existing point.
              if (Vector3F.AreNumericallyEqual(point, _mesh.Vertex.Position)
              || Vector3F.AreNumericallyEqual(point, _mesh.Vertex.Edge.Twin.Origin.Position))
            return;

              var edge = _mesh.Vertex.Edge;
              var collinearity = DcelMesh.GetCollinearity(point, _mesh.Vertex.Edge);
              switch (collinearity)
              {
            case Collinearity.CollinearBefore:     // The point is the new start of the line segment.
              edge.Origin.Position = point;
              _mesh.Dirty = true;
              return;
            case Collinearity.CollinearAfter:      // The point is the new end of the line segment.
              edge.Twin.Origin.Position = point;
              _mesh.Dirty = true;
              return;
            case Collinearity.CollinearContained:  // The point is in the line segment.
              // Point is in convex hull.
              return;
              }

              Debug.Assert(collinearity == Collinearity.NotCollinear
                   || collinearity == Collinearity.NotCollinearBehind
                   || collinearity == Collinearity.NotCollinearInFront);

              // Not Collinear --> Make triangle.
              _type = ConvexHullType.Planar;

              // Create new components.
              DcelVertex v0 = _mesh.Vertex;
              DcelVertex v1 = edge.Twin.Origin;

              DcelVertex v2 = new DcelVertex(point, null);
              DcelEdge e01 = edge;
              DcelEdge e10 = e01.Twin;
              DcelEdge e12 = new DcelEdge();
              DcelEdge e21 = new DcelEdge();
              DcelEdge e02 = new DcelEdge();
              DcelEdge e20 = new DcelEdge();
              DcelFace f012 = new DcelFace();
              DcelFace f210 = new DcelFace();

              // Link with existing components.
              e01.Next = e12; e01.Previous = e20;
              e10.Next = e02; e10.Previous = e21;

              // Link new components.
              v2.Edge = e20;

              e12.Origin = v1;
              e21.Origin = v2;
              e20.Origin = v2;
              e02.Origin = v0;

              e12.Twin = e21;
              e21.Twin = e12;
              e20.Twin = e02;
              e02.Twin = e20;

              e12.Previous = e01;
              e21.Previous = e02;
              e20.Previous = e12;
              e02.Previous = e10;

              e12.Next = e20;
              e21.Next = e10;
              e20.Next = e01;
              e02.Next = e21;

              // Link face.
              f012.Boundary = e01;
              f210.Boundary = e21;
              e01.Face = e12.Face = e20.Face = f012;
              e21.Face = e10.Face = e02.Face = f210;

              // Update _faces.
              _faces.Add(f012);
              _faces.Add(f210);

              _mesh.Dirty = true;

              Debug.Assert(_mesh.Faces.Count == _faces.Count, "Internal error in ConvexHullBuilder.");
              Debug.Assert(_mesh.IsTriangleMesh(), "DCEL mesh should be a triangle mesh.");
              Debug.Assert(_mesh.IsTwoSidedPolygon(), "DCEL mesh should be a two-sided polygon.");
        }
Пример #2
0
        /// <summary>
        /// Merges a point to an empty convex hull.
        /// </summary>
        /// <param name="point">The point.</param>
        private void GrowEmptyConvex(Vector3F point)
        {
            Debug.Assert(_mesh != null);
              Debug.Assert(_mesh.Vertices.Count == 0, "DCEL mesh is not empty.");
              Debug.Assert(_type == ConvexHullType.Empty);

              // Create a single vertex.
              _mesh.Vertex = new DcelVertex(point, null);
              _mesh.Dirty = true;
              _type = ConvexHullType.Point;
        }
Пример #3
0
        /// <summary>
        /// Merges a point to a convex hull that is also a point.
        /// </summary>
        /// <param name="point">The point.</param>
        private void GrowPointConvex(Vector3F point)
        {
            Debug.Assert(_mesh != null);
              Debug.Assert(_mesh.Vertices.Count == 1, "DCEL mesh with 1 vertex was expected.");
              Debug.Assert(_type == ConvexHullType.Point);

              // Abort if the point is equal to the existing point in the mesh.
              if (Vector3F.AreNumericallyEqual(_mesh.Vertex.Position, point))
            return;

              DcelVertex newVertex = new DcelVertex(point, null);
              DcelEdge edge = new DcelEdge();
              DcelEdge twin = new DcelEdge();

              // Link everything.
              edge.Origin = _mesh.Vertex;
              twin.Origin = newVertex;
              edge.Twin = twin;
              twin.Twin = edge;
              _mesh.Vertex.Edge = edge;
              newVertex.Edge = twin;

              _mesh.Dirty = true;
              _type = ConvexHullType.Linear;
        }
Пример #4
0
 public void Reset()
 {
     // Reset fields.
       _faces = new List<DcelFace>();
       _taggedEdges = new List<DcelEdge>();
       _isPlanar = false;
       _type = ConvexHullType.Empty;
       _mesh = new DcelMesh();
 }
Пример #5
0
        /// <summary>
        /// Removes the given face and connects the face edges to the given point.
        /// </summary>
        /// <param name="face">The face.</param>
        /// <param name="point">The point.</param>
        private void GrowPlanarConvexToSpatial(DcelFace face, Vector3F point)
        {
            _faces.Remove(face);

              // Create a new vertex for the point.
              DcelVertex newVertex = new DcelVertex(point, null);

              // Traverse the boundary of the face.
              DcelEdge currentEdge = face.Boundary;
              DcelEdge previousEdge = null;
              do
              {
            // Create new face.
            DcelFace newface = new DcelFace();
            newface.Boundary = currentEdge;
            currentEdge.Face = newface;

            _faces.Add(newface);

            // Create 2 half-edges.
            currentEdge.Next = new DcelEdge();
            currentEdge.Previous = new DcelEdge();

            currentEdge.Next.Face = newface;
            currentEdge.Next.Origin = currentEdge.Twin.Origin;
            currentEdge.Next.Previous = currentEdge;
            currentEdge.Next.Next = currentEdge.Previous;

            currentEdge.Previous.Face = newface;
            currentEdge.Previous.Origin = newVertex;
            currentEdge.Previous.Previous = currentEdge.Next;
            currentEdge.Previous.Next = currentEdge;

            // Link new face with previous new face.
            if (previousEdge != null)
            {
              previousEdge.Next.Twin = currentEdge.Previous;
              currentEdge.Previous.Twin = previousEdge.Next;
            }

            // Go to next edge.
            previousEdge = currentEdge;
            currentEdge = currentEdge.Twin.Previous.Twin;

            // Go on until no edge points to face anymore.
              } while (currentEdge.Face == face);

              // Link the last new face with the first new face.
              previousEdge.Next.Twin = currentEdge.Previous;
              currentEdge.Previous.Twin = previousEdge.Next;

              Debug.Assert(previousEdge != null);
              Debug.Assert(currentEdge == face.Boundary);
              Debug.Assert(currentEdge.Face != face);

              // Set the data for the new vertex.
              newVertex.Edge = currentEdge.Previous;

              _mesh.Dirty = true;
              _type = ConvexHullType.Spatial;

              Debug.Assert(_mesh.Faces.Count == _faces.Count, "Internal error in ConvexHullBuilder.");
        }