Найти выпуклый многоугольник охватывающий 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]);
        }
    }
}

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


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

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

7   голосов , оценка 4.286 из 5
Похожие ответы