Example #1
0
        public void SetCrossSection2D(Flat plane)
        {
            var paths        = new List <List <PointLight> >();
            var positivePath = new PolygonLight(MiscFunctions.Get2DProjectionPointsAsLight(PositiveLoop.VertexLoop, plane.Normal).ToList());

            if (positivePath.Area < 0)
            {
                positivePath.Path.Reverse();
            }
            paths.Add(positivePath.Path);
            foreach (var loop in NegativeLoops)
            {
                var negativePath = new PolygonLight(MiscFunctions.Get2DProjectionPointsAsLight(loop.VertexLoop, plane.Normal).ToList());
                if (negativePath.Area > 0)
                {
                    negativePath.Path.Reverse();
                }
                paths.Add(negativePath.Path);
            }
            CrossSection2D = PolygonOperations.Union(paths).Select(p => new PolygonLight(p)).ToList();
        }
Example #2
0
        internal CoincidentEdgeContactElement(Edge edge, Flat plane)
        {
            var avgFaceNormal = edge.OwnedFace.Normal.add(edge.OtherFace.Normal).divide(2);
            var edgeDir = plane.Normal.crossProduct(avgFaceNormal);
            if (edgeDir.dotProduct(edge.Vector) > 0)
            {
                StartVertex = edge.From;
                EndVertex = edge.To;
                SplitFacePositive = edge.OwnedFace; // the owned face is "above the flat plane
                SplitFaceNegative = edge.OtherFace; // the other face is below it
            }
            else
            {
                StartVertex = edge.To;
                EndVertex = edge.From;
                SplitFacePositive = edge.OtherFace; // the reverse from above. The other face is above the flat
                SplitFaceNegative = edge.OwnedFace;
                ReverseDirection = true;

            }
            ContactEdge = edge;
            // ContactEdge = new Edge(ReferenceStart, ReferenceEnd, null, null);
        }
Example #3
0
 internal ContactData(IEnumerable <SolidContactData> solidContactData, IEnumerable <IntersectionGroup> intersectionGroups, Flat plane)
 {
     SolidContactData   = new List <SolidContactData>(solidContactData);
     IntersectionGroups = new List <IntersectionGroup>(intersectionGroups);
     Plane = plane;
 }
Example #4
0
 internal static Boolean FindNegativeAndPositiveFaces(Flat plane, Vertex onPlaneVertex, double[] vertexDistancesToPlane, out PolygonalFace negativeFace, out PolygonalFace positiveFace)
 {
     negativeFace = null;
     positiveFace = null;
     foreach (var face in onPlaneVertex.Faces)
     {
         var otherEdge = face.OtherEdge(onPlaneVertex);
         var toDistance = vertexDistancesToPlane[otherEdge.To.IndexInList];
         var fromDistance = vertexDistancesToPlane[otherEdge.From.IndexInList];
         if ((toDistance > 0 && fromDistance < 0) || (toDistance < 0 && fromDistance > 0))
             if ((toDistance > 0) == (face == otherEdge.OwnedFace))
                 positiveFace = face;
             else negativeFace = face;
     }
     return (negativeFace != null && positiveFace != null);
 }
Example #5
0
 internal ThroughFaceContactElement(Flat plane, Edge edge, double toDistance)
 {
     PolygonalFace negativeFace, positiveFace;
     if (toDistance > 0)
     {
         positiveFace = edge.OtherFace;
         negativeFace = edge.OwnedFace;
     }
     else
     {
         negativeFace = edge.OtherFace;
         positiveFace = edge.OwnedFace;
     }
     SplitEdge = edge;
     SplitFaceNegative = negativeFace;
     SplitFacePositive = positiveFace;
     StartVertex = GeometryFunctions.PointOnPlaneFromIntersectingLine(
         plane.Normal, plane.DistanceToOrigin, edge.From, edge.To);
 }
Example #6
0
 /// <summary>
 /// Gets the in plane flat.
 /// </summary>
 /// <param name="startFace">The start face.</param>
 /// <returns>Flat.</returns>
 private static Flat GetInPlaneFlat(PolygonalFace startFace)
 {
     var flat = new Flat(new List<PolygonalFace>(new[] { startFace }));
     var visitedFaces = new HashSet<PolygonalFace>(startFace.AdjacentFaces);
     visitedFaces.Add(startFace);
     var stack = new Stack<PolygonalFace>(visitedFaces);
     while (stack.Any())
     {
         var face = stack.Pop();
         if (!flat.IsNewMemberOf(face)) continue;
         flat.UpdateWith(face);
         foreach (var adjacentFace in face.AdjacentFaces)
             if (!visitedFaces.Contains(adjacentFace))
             {
                 visitedFaces.Add(adjacentFace);
                 stack.Push(adjacentFace);
             }
     }
     return flat;
 }
Example #7
0
        internal static void MakeInPlaneContactElement(Flat plane, Edge edge, HashSet<Edge> edgeHashSet, double[] vertexDistancesToPlane, List<CoincidentEdgeContactElement> contactElts)
        {
            // the edge is in the plane. Let's look at details on the two faces that meet at that edge.
            // ownedFaceOtherVertex is the vertex of the face of the in-plane edge that is NOT on the plane...
            // it's the "other" vertex
            var ownedFaceOtherVertex = edge.OwnedFace.OtherVertex(edge);
            // the distance to the flat plane for the other vertex.
            var distPlaneOwned = vertexDistancesToPlane[ownedFaceOtherVertex.IndexInList];
            // repeat for the other face of the in-plane edge
            var otherFaceOtherVertex = edge.OtherFace.OtherVertex(edge);
            var distPlaneOther = vertexDistancesToPlane[otherFaceOtherVertex.IndexInList];

            // here, we check to see if the faces are on either side of the flat plane, if they are
            // then we make a
            if ((distPlaneOwned > 0 && distPlaneOther < 0) || (distPlaneOwned < 0 && distPlaneOther > 0))
            {
                RemoveNeighboringEdgesToo(edgeHashSet, edge);
                //remove the edges of the faces from the hash to speed things along
                contactElts.Add(new CoincidentEdgeContactElement(edge, plane));
                return;
            }
            // if faces are not on either side, check to see if one of the faces is
            // in the same plane as flat. If so, then do a depth first search with "GetInPlaneFlat"
            // to build up that section of faces.
            Flat inPlaneFlat;
            if (StarMath.IsNegligible(distPlaneOwned)) inPlaneFlat = GetInPlaneFlat(edge.OwnedFace);
            else if (StarMath.IsNegligible(distPlaneOther)) inPlaneFlat = GetInPlaneFlat(edge.OtherFace);
            else //if neither face is in the plane then you have an edge which is a knife on the plane
            {
                // either on the positive side or the negative side. Doesn't matter which one - we don't want it (i.e. continue).
                RemoveNeighboringEdgesToo(edgeHashSet, edge);
                //remove the edges of the faces from the hash to speed things along
                return;
            }
            foreach (var innerEdge in inPlaneFlat.InnerEdges) edgeHashSet.Remove(innerEdge);
            foreach (var outerEdge in inPlaneFlat.OuterEdges)
            {
                edgeHashSet.Remove(outerEdge);
                contactElts.Add(new CoincidentEdgeContactElement(outerEdge, plane));
            }
        }