Найти выпуклый многоугольник охватывающий N точек на плоскости - C#

Узнай цену своей работы

Формулировка задачи:

N точек на плоскости заданы своими координатами. Найти такой минимальный по площади выпуклый многоугольник, что все N точек лежат либо внутри этого многоугольника, либо на его границе (такой выпуклый многоугольник называется выпуклой оболочкой).

Решение задачи: «Найти выпуклый многоугольник охватывающий N точек на плоскости»

textual
Листинг программы
  1. using System;
  2. using System.Linq;
  3. using System.Collections.Generic;
  4.  
  5. class Point : IComparable<Point>
  6. {
  7.     private double[] coordinates = new double[2];
  8.  
  9.     public Point(double x, double y)
  10.     {
  11.         coordinates[0] = x;
  12.         coordinates[1] = y;
  13.     }
  14.  
  15.     public double this[int index]
  16.     {
  17.         get { return coordinates[index]; }
  18.     }
  19.  
  20.     public double Distance(Point other)
  21.     {
  22.         double dx = this[0] - other[0];
  23.         double dy = this[1] - other[1];
  24.         return Math.Sqrt(dx * dx + dy * dy);
  25.     }
  26.  
  27.     public override string ToString()
  28.     {
  29.         return String.Format("({0}; {1})", this[0], this[1]);
  30.     }
  31.  
  32.     public int CompareTo(Point other)
  33.     {
  34.         int compare = Math.Sign(other[1] - this[1]);
  35.         if (compare == 0) compare = Math.Sign(this[0] - other[0]);
  36.         return compare;
  37.     }
  38. }
  39.  
  40. class Line : IComparable<Line>
  41. {
  42.     private Point[] points = new Point[2];
  43.     private double? alpha = null;
  44.     private double? length = null;
  45.  
  46.     public Line(Point a, Point b)
  47.     {
  48.         points[0] = a;
  49.         points[1] = b;
  50.     }
  51.  
  52.     public Point this[int index]
  53.     {
  54.         get { return points[index]; }
  55.     }
  56.  
  57.     public double Alpha
  58.     {
  59.         get
  60.         {
  61.             if (alpha == null)
  62.             {
  63.                 alpha = Math.Atan2(this[1][1] - this[0][1], this[1][0] - this[0][0]);
  64.                 if (alpha < 0.0) alpha += Math.PI + Math.PI;
  65.             }
  66.             return (double)alpha;
  67.         }
  68.     }
  69.  
  70.     public double Length
  71.     {
  72.         get
  73.         {
  74.             if (length == null)
  75.             {
  76.                 length = this[0].Distance(this[1]);
  77.             }
  78.             return (double)length;
  79.         }
  80.     }
  81.  
  82.     public int CompareTo(Line other)
  83.     {
  84.         int compare = Math.Sign(this.Alpha - other.Alpha);
  85.         if (compare == 0) compare = Math.Sign(other.Length - this.Length);
  86.         return compare;
  87.     }
  88. }
  89.  
  90. class Corner : IComparable<Corner>
  91. {
  92.     private Line[] lines = new Line[2];
  93.     private double? phi = null;
  94.  
  95.     public Corner(Line ab, Point c)
  96.     {
  97.         lines[0] = ab;
  98.         lines[1] = new Line(ab[1], c);
  99.     }
  100.  
  101.     public Line this[int index]
  102.     {
  103.         get { return lines[index]; }
  104.     }
  105.  
  106.     public double Phi
  107.     {
  108.         get
  109.         {
  110.             if (phi == null)
  111.             {
  112.                 phi = this[1].Alpha - this[0].Alpha;
  113.                 if (phi < 0.0) phi += Math.PI + Math.PI;
  114.             }
  115.             return (double)phi;
  116.         }
  117.     }
  118.  
  119.     public int CompareTo(Corner other)
  120.     {
  121.         int compare = Math.Sign(this.Phi - other.Phi);
  122.         if (compare == 0) compare = Math.Sign(other[1].Length - this[1].Length);
  123.         return compare;
  124.     }
  125. }
  126.  
  127. class Program
  128. {
  129.     public static void Main()
  130.     {
  131.         List<Point> points = new List<Point>();
  132.         for (int i = -2; i <= 2; i++)
  133.         {
  134.             for (int j = -2; j <= 2; j++)
  135.             {
  136.                 points.Add(new Point((double)i, (double)j));
  137.             }
  138.         }
  139.         Point first = points.Max();
  140.         Line last = points
  141.             .Where(p => p.CompareTo(first) != 0)
  142.             .Select(p => new Line(first, p))
  143.             .Min();
  144.         List<Line> lines = new List<Line>();
  145.         lines.Add(last);
  146.         while ((last = lines[lines.Count - 1])[1].CompareTo(first) != 0)
  147.         {
  148.             Corner corner = points
  149.                 .Where(p => p.CompareTo(last[0]) != 0 && p.CompareTo(last[1]) != 0)
  150.                 .Select(p => new Corner(last, p))
  151.                 .Min();
  152.             lines.Add(corner[1]);
  153.         }
  154.         foreach (Line line in lines)
  155.         {
  156.             Console.WriteLine(line[0]);
  157.         }
  158.     }
  159. }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

7   голосов , оценка 4.286 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы