/// <summary> /// Does this ray intersect with the provided face? /// </summary> /// <param name="face">The Face to intersect with.</param> /// <param name="result">The intersection result.</param> /// <returns>True if an intersection occurs, otherwise false. If true, check the intersection result for the location of the intersection.</returns> internal bool Intersects(Face face, out Vector3 result) { var plane = face.Plane(); if (Intersects(plane, out Vector3 intersection)) { var boundaryPolygon = face.Outer.ToPolygon(); var voids = face.Inner?.Select(v => v.ToPolygon())?.ToList(); var transformToPolygon = new Transform(plane.Origin, plane.Normal); var transformFromPolygon = new Transform(transformToPolygon); transformFromPolygon.Invert(); var transformedIntersection = transformFromPolygon.OfVector(intersection); IEnumerable <Line> curveList = boundaryPolygon.Segments(); if (voids != null) { curveList = curveList.Union(voids.SelectMany(v => v.Segments())); } curveList = curveList.Select(l => transformFromPolygon.OfLine(l)); if (Polygon.Contains(curveList, transformedIntersection, out _)) { result = intersection; return(true); } } result = default(Vector3); return(false); }
/// <summary> /// Check for self-intersection in the supplied line segment collection. /// </summary> /// <param name="t">The transform representing the plane of the polygon.</param> /// <param name="segments"></param> internal static void CheckSelfIntersectionAndThrow(Transform t, IList <Line> segments) { var segmentsTrans = new List <Line>(); foreach (var l in segments) { segmentsTrans.Add(t.OfLine(l)); } ; for (var i = 0; i < segmentsTrans.Count; i++) { for (var j = 0; j < segmentsTrans.Count; j++) { if (i == j) { // Don't check against itself. continue; } if (segmentsTrans[i].Intersects2D(segmentsTrans[j])) { throw new ArgumentException($"The polyline could not be created. Segments {i} and {j} intersect."); } } } }