Найти выпуклый многоугольник охватывающий N точек на плоскости - C#
Формулировка задачи:
N точек на плоскости заданы своими координатами. Найти такой минимальный по площади выпуклый многоугольник, что все N точек лежат либо внутри этого многоугольника, либо на его границе (такой выпуклый многоугольник называется выпуклой оболочкой).
Решение задачи: «Найти выпуклый многоугольник охватывающий N точек на плоскости»
textual
Листинг программы
using System; using System.Linq; using System.Collections.Generic; class Point : IComparable<Point> { private double[] coordinates = new double[2]; public Point(double x, double y) { coordinates[0] = x; coordinates[1] = y; } public double this[int index] { get { return coordinates[index]; } } public double Distance(Point other) { double dx = this[0] - other[0]; double dy = this[1] - other[1]; return Math.Sqrt(dx * dx + dy * dy); } public override string ToString() { return String.Format("({0}; {1})", this[0], this[1]); } public int CompareTo(Point other) { int compare = Math.Sign(other[1] - this[1]); if (compare == 0) compare = Math.Sign(this[0] - other[0]); return compare; } } class Line : IComparable<Line> { private Point[] points = new Point[2]; private double? alpha = null; private double? length = null; public Line(Point a, Point b) { points[0] = a; points[1] = b; } public Point this[int index] { get { return points[index]; } } public double Alpha { get { if (alpha == null) { alpha = Math.Atan2(this[1][1] - this[0][1], this[1][0] - this[0][0]); if (alpha < 0.0) alpha += Math.PI + Math.PI; } return (double)alpha; } } public double Length { get { if (length == null) { length = this[0].Distance(this[1]); } return (double)length; } } public int CompareTo(Line other) { int compare = Math.Sign(this.Alpha - other.Alpha); if (compare == 0) compare = Math.Sign(other.Length - this.Length); return compare; } } class Corner : IComparable<Corner> { private Line[] lines = new Line[2]; private double? phi = null; public Corner(Line ab, Point c) { lines[0] = ab; lines[1] = new Line(ab[1], c); } public Line this[int index] { get { return lines[index]; } } public double Phi { get { if (phi == null) { phi = this[1].Alpha - this[0].Alpha; if (phi < 0.0) phi += Math.PI + Math.PI; } return (double)phi; } } public int CompareTo(Corner other) { int compare = Math.Sign(this.Phi - other.Phi); if (compare == 0) compare = Math.Sign(other[1].Length - this[1].Length); return compare; } } class Program { public static void Main() { List<Point> points = new List<Point>(); for (int i = -2; i <= 2; i++) { for (int j = -2; j <= 2; j++) { points.Add(new Point((double)i, (double)j)); } } Point first = points.Max(); Line last = points .Where(p => p.CompareTo(first) != 0) .Select(p => new Line(first, p)) .Min(); List<Line> lines = new List<Line>(); lines.Add(last); while ((last = lines[lines.Count - 1])[1].CompareTo(first) != 0) { Corner corner = points .Where(p => p.CompareTo(last[0]) != 0 && p.CompareTo(last[1]) != 0) .Select(p => new Corner(last, p)) .Min(); lines.Add(corner[1]); } foreach (Line line in lines) { Console.WriteLine(line[0]); } } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д