private static void Render(IEnumerable<LineSegment2> allLineSegments, Intersection[] intersections) { var allPoints = allLineSegments.SelectMany(l => new[] { l.End1, l.End2 }).Concat(intersections.Select(i => i.Point)).ToList(); var width = (int)Math.Ceiling(allPoints.Max(p => p.X)); var height = (int)Math.Ceiling(allPoints.Max(p => p.Y)); var linePen = new Pen(Color.White, 5); var selectedLinePen = new Pen(Color.Yellow, 8); var quadrilateralPen = new Pen(Color.Red, 5); var form = new Form { ClientSize = new Size(width, height) }; var bitmap = new Bitmap(width, height); using (var g = Graphics.FromImage(bitmap)) { g.Clear(Color.Black); foreach (var line in _sampleLineSegments) g.DrawLine(linePen, (float)line.End1.X, (float)line.End1.Y, (float)line.End2.X, (float)line.End2.Y); foreach (var line in intersections.SelectMany(i => new[] { i.Line1, i.Line2 }).Distinct()) g.DrawLine(selectedLinePen, (float)line.End1.X, (float)line.End1.Y, (float)line.End2.X, (float)line.End2.Y); g.DrawPolygon(quadrilateralPen, intersections.Select(i => new PointF((float)i.Point.X, (float)i.Point.Y)).ToArray()); } form.Controls.Add(new PictureBox { Image = bitmap, Width = width, Height = height }); form.ShowDialog(); }
private static double CalculateError(Intersection[] intersections) { var distanceError = intersections.Sum( intersection => { Func<double, double> calcDistancePenalty = d => { if (d > 0 && d < 1) { // Itersection within the line segment is a bad sign, so penalise for it, proportionally return -Math.Log(d > 0.5 ? 1 - d : d); } return 0; }; return calcDistancePenalty(intersection.Distance1) + calcDistancePenalty(intersection.Distance2); } ); var angles = new[] { GetAcuteAngleBetweenPoints(intersections[0].Point, intersections[1].Point, intersections[2].Point), GetAcuteAngleBetweenPoints(intersections[1].Point, intersections[2].Point, intersections[3].Point), GetAcuteAngleBetweenPoints(intersections[2].Point, intersections[3].Point, intersections[0].Point), GetAcuteAngleBetweenPoints(intersections[3].Point, intersections[0].Point, intersections[1].Point) }; // Sum of squared errors const double piOnTwo = Math.PI/2; var angleError = angles.Sum(angle => Math.Pow(piOnTwo - Math.Abs(angle), 2)); return angleError + distanceError; }