МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
ЗАПОРІЗЬКИЙ НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ
МАТЕМАТИЧНИЙ ФАКУЛЬТЕТ
КАФЕДРА ПРОГРАМНОЇ ІНЖЕНЕРІЇ
Дисципліна «Практикум з програмування»
Лабораторна робота 5
Виконав студент гр. 6.1219-2
Тимошенко Данил Вячеславович
Перевірила доцент кафедри фундаментальної і
прикладної математики, к. ф.-м. н.
Ткаченко Ірина Григорівна
Запоріжжя
2021
1 ЗАВДАННЯ
2 ХІД ВИКОНАННЯ РОБОТИ
Код програми для завдання
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
using System.Globalization;
class Point
{
public double X { get; private set; }
public double Y { get; private set; }
public Point (double x, double y)
{
this.X = x;
this.Y = y;
}
}
static class Program
{
// путь к входному файлу по умолчанию
static string InputFileName = "input.txt";
// Векторное произведение 2 векторов с общим
// началом origin и концами end1 и end2.
//
static double VectorProd (Point origin, Point end1, Point end2) {
// Координаты первого вектора
double x1 = end1.X - origin.X, y1 = end1.Y - origin.Y;
// Координаты 2го вектора
double x2 = end2.X - origin.X, y2 = end2.Y - origin.Y;
// Само векторное произведение
return x1 * y2 - x2 * y1;
}
// косинус угла между векторами с общим
// началом origin и концами end1 и end2.
//
static double Cos (Point origin, Point end1, Point end2) {
// Координаты первого вектора
double x1 = end1.X - origin.X, y1 = end1.Y - origin.Y;
// Координаты 2го вектора
double x2 = end2.X - origin.X, y2 = end2.Y - origin.Y;
return x1 * x2 + y1 * y2 / (Math.Sqrt(x1*x1 + y1*y1) + Math.Sqrt(x2*x2 + y2*y2));
}
// Вычислить площадь выпуклого многоугольника, описанного
// вокруг данного набора точек.
//
static double ConvexArea (Point[] points) {
// Кол-во точек
int size = points.Length;
// Если меньше 3 точек, площадь вычислить невозможно
if (size < 3) return 0;
// результат - площадь многоугольника
double result = 0;
// Отметки использованных точек
bool[] used = new bool[size];
// Найти самую правую точку - у которой максимальное значение X
Point mostRight = points[0];
int mostRightIndex = 0;
for (int i=0; iif (mostRight.X < points[i].X) {
mostRight = points[i];
mostRightIndex = i;
}
}
Console.WriteLine("[debug]: Point: ({0}, {1})", mostRight.X, mostRight.Y);
// Отметить что самая правая точка была использована
used[mostRightIndex] = true;
Point current = mostRight;
Point previous = null;
do {
double biggestCos = -1;
int nextIndex = -1;
if (current == mostRight){
previous = new Point(current.X, current.Y - 10);
}
// Находим следующую не использованную точку, которая
// находится снаружи и слева от текущей точки
for (int i=0; i// Если точка уже была использована - пропускаем ее.
if (i != mostRightIndex && used[i]) continue;
// Посчитать векторное произведение для этой точки
double nextVectorProd = VectorProd (previous, current, points[i]);
double nextCos = Cos (previous, current, points[i]);
// Если это наименьший левый угол, то запомнить индекс точки
// и значение косинуса угла
if (nextVectorProd > 0 && biggestCos < nextCos){
biggestCos = nextCos;
nextIndex = i;
}
}
if (nextIndex == -1) return result;
// Отметить что точка используется
Point next = points[nextIndex];
used[nextIndex] = true;
Console.WriteLine("[debug]: Point: ({0}, {1})", next.X, next.Y);
// Прибавить площадь треугольника к общей площади.
// Площадь вычисляется по формуле векторного
// произведения и делится на 2.
if (current != mostRight) {
result += VectorProd(mostRight, current, next) / 2.0;
}
// Переключиться на следующую точку
previous = current;
current = next;
// Повторять пока не вернемся к самой правой точке
} while (current != mostRight);
return result;
}
// Содержимое входного файла (по умолчанию - input.txt):
// N
// x[0] y[0]
// ...
// x[N-1] y[N-1]
//
public static void Main(string[] args)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("en");
var previousOutEncoding = Console.OutputEncoding;
var previuosInEncoding = Console.InputEncoding;
Console.OutputEncoding = Encoding.UTF8;
Console.InputEncoding = Encoding.Unicode;
// Входные данные
string[] inputData;
// Считать входные данные из файла
try {
if (args.Length > 0) InputFileName = args[0];
inputData = File.ReadAllLines(InputFileName);
}
catch (IOException){
Console.Write("Input file '{0}' not found. \n", InputFileName);
return;
}
// Количество точек
int N = int.Parse(inputData[0]);
// Массив точек
Point[] points = new Point[N];
// Обработать все точки
for (int i = 0; i < N; i++) {
string[] xy = inputData[i+1].Split(' ');
points[i] = new Point(double.Parse(xy[0]), double.Parse(xy[1]));
}
// Вычислить площадь выпуклого многоугольника
double result = ConvexArea(points);
Console.Write ("Площа опуклого многокутника: {0} \n", result);
// Reset console encoding
Console.OutputEncoding = previousOutEncoding;
Console.InputEncoding = previuosInEncoding;
}
}
Робота програми для завдання
Достарыңызбен бөлісу: |