public static LineSegment2D MergeSegments(LineSegment2D[] segments) { var points = segments.Select(s => s.P1).Union(segments.Select(s => s.P2)).ToArray(); var a = (double) points.Length*points.Sum(p => p.X*p.Y) - points.Sum(p => p.X)*points.Sum(p => p.Y); a /= points.Length*points.Sum(p => p.X*p.X) - Math.Pow(points.Sum(p => p.X), 2); var b = (points.Sum(p => p.Y) - a*points.Sum(p => p.X))/points.Length; var y1 = points.Min(p => p.Y); var y2 = points.Max(p => p.Y); var x1 = (int) ((y1 - b)/a); var x2 = (int) ((y2 - b)/a); return new LineSegment2D(new Point(x1, y1), new Point(x2, y2)); }
public static List<Rectangle> Compute(Size imageSize, LineSegment2D[] lines) { const double scaleStep = 0.5; const double minScale = 0.1; const double ratio = 1.5; var allLines = lines.Select(RotateLineSegment2D).ToArray(); var left = default(LineSegment2D); var right = default(LineSegment2D); var leftPoint = new Point(int.MinValue, 0); var rightPoint = new Point(int.MaxValue, 0); var viewPoint = imageSize.Width/2; foreach (var line in allLines) { var start = FindStartingPoint(line, imageSize.Width, imageSize.Height, false); if (start.X >= leftPoint.X && start.X <= viewPoint) { left = line; leftPoint = start; } else if (start.X <= rightPoint.X && start.X > viewPoint) { right = line; rightPoint = start; } } var maxY = Math.Min(FindStartingPoint(left, imageSize.Width, imageSize.Height, true).Y, FindStartingPoint(right, imageSize.Width, imageSize.Height, true).Y); leftPoint = FindStartingPoint(left, imageSize.Width, maxY, false); rightPoint = FindStartingPoint(right, imageSize.Width, maxY, false); var intersection = Intersection(left, right); var windowSize = rightPoint.X - leftPoint.X; var windowMiddlePoint = new Point(leftPoint.X + windowSize/2, leftPoint.Y); var windowDirection = new PointF(-(left.Direction.X + right.Direction.X*left.Direction.Y/right.Direction.Y)/2, -left.Direction.Y); var middleDistance = (float) Math.Sqrt(windowDirection.X*windowDirection.X + windowDirection.Y*windowDirection.Y); windowDirection = new PointF(windowDirection.X/middleDistance, windowDirection.Y/middleDistance); //calculate step count var stepCount = 0; var temp = minScale; do { temp = temp/scaleStep; ++stepCount; } while (temp < 1); var coefficient = DistanceHelper.Distance(windowMiddlePoint, intersection); var scale = 1.0; var windows = new List<Rectangle>(); for (var i = 0; i < stepCount; ++i) { var windowWidth = windowSize*scale; var windowHeight = windowWidth/ratio; var length = (1.0 - scale)*coefficient; var position = new Point((int) (windowMiddlePoint.X + windowDirection.X*length), (int) (windowMiddlePoint.Y + windowDirection.Y*length)); var windowLeft = position.X - windowWidth/2; var windowDown = position.Y - windowHeight; windows.Add(new Rectangle((int) windowLeft, (int) windowDown, (int) windowWidth, (int) windowHeight)); scale *= scaleStep; } return windows; }