/// <summary> /// Splits the path by the supplied by line /// </summary> /// <param name="path">Path to split</param> /// <param name="cutter">Cutter to cut the path by</param> /// <returns>An enumeration of parts, or a single part if not split occurred</returns> public static IEnumerable <ILucidLine> Split(IEnumerable <IPoint> path, ILucidLine cutter) { var current = new LucidLine(); current.AddVertex(path.First()); foreach (var vertices in path.SlidingWindow(2)) { var line = new AlgebraicLine(vertices); var lineExtent = CalculateExtent(line); foreach (var cutterLine in cutter.Vertices.SlidingWindow(2)) { var byLine = new AlgebraicLine(cutterLine); var intersection = Intersection(line, byLine); if (intersection != null && Intersects(intersection, lineExtent) && Intersects(intersection, CalculateExtent(byLine))) { current.AddVertex(intersection); yield return(current); current = new LucidLine(); current.AddVertex(intersection); break; } } current.AddVertex(line.End); } yield return(current); }
public static IEnumerable <ILucidVertex> RemoveSelfIntersections(ILucidLine lineIn) { var segments = (from s in lineIn.Vertices.SlidingWindow(2) select s).Where(w => w.Count() == 2).ToArray(); var state = true; foreach (var segment in segments) { if (state == true) { yield return(segment.First()); } foreach (var otherSegment in from s in segments where s != segment select s) { var intersect = GeometryHelper.LineIntersections(LucidLine.Create(segment), LucidLine.Create(otherSegment)).Any(); if (intersect) { state = !state; break; } } } yield return(lineIn.Vertices.Last()); }
public static ILucidLine FixDuplicateVertices(ILucidLine geometry, int precision = 2) { var vertexHash = new HashSet <string>(); var newVertices = new List <ILucidVertex>(); var vertices = geometry.Vertices.ToArray(); for (int i = 0; i < vertices.Length; i++) { var vertex = vertices[i]; var id = vertex.ToString(precision); if (!vertexHash.Contains(id)) { vertexHash.Add(id); newVertices.Add(vertex); } else if (i == vertices.Length - 1) { // We want to remove the interior duplicate not the last vertex newVertices.Remove(newVertices.First(v => v.ToString(precision) == id)); newVertices.Add(vertex); } } var lineOut = LucidLine.Create(newVertices); return(lineOut); }
public static double Length(ILucidLine line) { double length = 0; foreach (var subline in line.Vertices.SlidingWindow(2)) { length += Math.Abs(GeometryHelper.DistanceBetween(subline.First(), subline.Last())); } return(length); }
public static bool IsCoincident(ILucidLine first, ILucidLine second) { foreach (var vertex in first.Vertices) { if (!Intersects(vertex, second)) { return(false); } } return(true); }
/// <summary> /// Returns the nearest line segment from a line /// </summary> /// <param name="wholeLine"></param> /// <param name="referencePoint"></param> /// <returns></returns> public static ILucidLine NearestLineSegment(ILucidLine wholeLine, IPoint referencePoint) { if (wholeLine.Vertices.Count() == 2) { return(wholeLine); } var vertices = wholeLine.Vertices.SlidingWindow(2); var first = LucidLine.Create(vertices.First()); var last = LucidLine.Create(vertices.Last()); var nearest = NearestGeometry(referencePoint, first, last).First(); return((ILucidLine)nearest); }
public static bool Intersects(IPoint point, ILucidLine line, bool infinitLine = false, int precision = 1) { var coincidentPoint = line.Vertices.Where(v => v.IsCoincident(point)).FirstOrDefault(); if (coincidentPoint == null) { var pointLine = LucidLine.Create(new IPoint[] { new LucidPoint(0, 0), point }); var intersection = LineIntersections(pointLine, line, infinitLine).FirstOrDefault(); if (intersection == null || !GeometryHelper.IsCoincident(intersection, point, precision)) { return(false); } } return(true); }
public static IEnumerable <IPoint> LineIntersections(ILucidLine first, ILucidLine second, bool infinitLines = false) { var firstExtent = CalculateExtent(first); var secondExtent = CalculateExtent(second); if (infinitLines || GeometryHelper.Intersects(first, second)) { foreach (var firstLine in from p in first.Vertices.TumblingWindow(2) select new AlgebraicLine(p.First(), p.Last())) { foreach (var secondLine in from p in second.Vertices.TumblingWindow(2) select new AlgebraicLine(p.First(), p.Last())) { var intersection = Intersection(firstLine, secondLine); if (intersection != null && (infinitLines || (GeometryHelper.Intersects(intersection, firstExtent) && GeometryHelper.Intersects(intersection, secondExtent)))) { yield return(intersection); } } } } }
public static IEnumerable <ILucidLine> Split(ILucidLine lineIn, ILucidLine by) { return(Split(lineIn.Vertices, by)); }
public static bool SelfIntersects(ILucidLine lineIn) { return(RemoveSelfIntersections(lineIn).Count() != lineIn.Vertices.Count()); }