private int FindBorder(Segment segment, Size rectangleSize, Segment.Type borderType) { if (!Segment.Horizontal(borderType)) { int topRectSide = segment.SegmentType == Segment.Type.Top ? segment.End.Y - rectangleSize.Height : segment.End.Y; int bottomRectSide = topRectSide + rectangleSize.Height; var side = new Segment(0, topRectSide, 0, bottomRectSide, borderType); Segment border; if (borderType == Segment.Type.Left) { border = BorderSegments .Where(x => x.SegmentType == Segment.OppositeType(borderType) && x.Start.X <= segment.Start.X && x.Intersects(side)) .OrderByDescending(x => x.Start.X) .FirstOrDefault(); } else { border = BorderSegments .Where(x => x.SegmentType == Segment.OppositeType(borderType) && x.Start.X >= segment.End.X && x.Intersects(side)) .OrderBy(x => x.Start.X) .FirstOrDefault(); } return((border == null) ? (borderType == Segment.Type.Left ? -100000 : 100000) : border.Start.X); } else { int leftRectSide = segment.SegmentType == Segment.Type.Left ? segment.End.X - rectangleSize.Width : segment.End.X; int rightRectSide = leftRectSide + rectangleSize.Width; var side = new Segment(leftRectSide, 0, rightRectSide, 0, borderType); Segment border; if (borderType == Segment.Type.Top) { border = BorderSegments .Where(x => x.SegmentType == Segment.OppositeType(borderType) && x.Start.Y <= segment.Start.Y && x.Intersects(side)) .OrderByDescending(x => x.Start.Y) .FirstOrDefault(); } else { border = BorderSegments .Where(x => x.SegmentType == Segment.OppositeType(borderType) && x.End.Y >= segment.End.Y && x.Intersects(side)) .OrderBy(x => x.Start.Y) .FirstOrDefault(); } return((border == null) ? (borderType == Segment.Type.Top ? -100000 : 100000) : border.Start.Y); } }
private bool CheckOppositeBorder(Point rectanglePos, Size rectangleSize, Segment.Type segmentType) { var rectangle = new Rectangle(rectanglePos, rectangleSize); var intersects = BorderSegments.Where(x => rectangle.IsIntersected(x)); if (intersects.Count() == 0) { return(true); } return(false); }
private static List <Segment> RemoveIntersections(List <Segment> segments, int coord, Segment.Type type) { List <SegmentPoint> points = new List <SegmentPoint>(); List <Segment> outSegments = new List <Segment>(); foreach (var segment in segments) { if (Segment.Horizontal(type)) { points.Add(new SegmentPoint(segment.Start.X, segment.SegmentType, SegmentPoint.PointType.Start)); points.Add(new SegmentPoint(segment.End.X, segment.SegmentType, SegmentPoint.PointType.End)); } else { points.Add(new SegmentPoint(segment.Start.Y, segment.SegmentType, SegmentPoint.PointType.Start)); points.Add(new SegmentPoint(segment.End.Y, segment.SegmentType, SegmentPoint.PointType.End)); } } Segment.Type currentType = points[0].SegmentType; var currentPoint = points[0]; var startFound = true; bool isIntersection = false; bool isFirst = true; int lastAdded = int.MinValue; var sortedPoints = points.OrderBy(x => x.Coordinates).ToList(); for (int i = 0; i < sortedPoints.Count - 1; i++) { if (sortedPoints[i].Coordinates == sortedPoints[i + 1].Coordinates && sortedPoints[i].SegmentType == sortedPoints[i + 1].SegmentType) { sortedPoints[i].Type = SegmentPoint.PointType.Start; sortedPoints[i + 1].Type = SegmentPoint.PointType.Start; /*удаление из середины листа слишком долгая операция, сделаем точку стартовой * и она не будет рассматриваться в автомате */ } } foreach (var point in sortedPoints) { if (isFirst) { currentType = point.SegmentType; currentPoint = point; startFound = true; isFirst = false; continue; } if (isIntersection) { startFound = true; currentPoint = point; currentType = Segment.OppositeType(point.SegmentType); isIntersection = false; continue; } if (!startFound && point.Type == SegmentPoint.PointType.Start) { if (lastAdded == point.Coordinates && outSegments.Last().SegmentType == point.SegmentType) { var lastSegment = outSegments.Last(); outSegments.RemoveAt(outSegments.Count - 1); startFound = true; if (Segment.Horizontal(type)) { currentPoint = new SegmentPoint(lastSegment.Start.X, point.SegmentType, SegmentPoint.PointType.Start); } else { currentPoint = new SegmentPoint(lastSegment.Start.Y, point.SegmentType, SegmentPoint.PointType.Start); } continue; } currentPoint = point; startFound = true; currentType = point.SegmentType; continue; } if (startFound && point.SegmentType == currentType && point.Type == SegmentPoint.PointType.End) { if (Segment.Horizontal(type)) { outSegments.Add(new Segment(currentPoint.Coordinates, coord, point.Coordinates, coord, currentType)); } else { outSegments.Add(new Segment(coord, currentPoint.Coordinates, coord, point.Coordinates, currentType)); } lastAdded = point.Coordinates; startFound = false; continue; } if (startFound && point.SegmentType != currentType) { if (Segment.Horizontal(type)) { outSegments.Add(new Segment(currentPoint.Coordinates, coord, point.Coordinates, coord, currentType)); } else { outSegments.Add(new Segment(coord, currentPoint.Coordinates, coord, point.Coordinates, currentType)); } lastAdded = point.Coordinates; startFound = false; isIntersection = true; continue; } } return(outSegments.Where(x => x.Length > 0).ToList()); }
public SegmentPoint(int coordinates, Segment.Type segmentType, PointType type) { Coordinates = coordinates; SegmentType = segmentType; Type = type; }