Задание:
- Задать фигуру, имеющую внутренние и внешние треугольники.
- Создать файлы, в которых будут записаны координаты вершин и узлы треугольников.
- Реализовать программно чтение данных из файла и конвертацию их в числовые массивы координат и треугольников.
- Преобразовать координаты из естественной в экранную систему координат.
- Нарисовать полученную фигуру.
- Выполнить анализ и найти внутренние треугольники.
- Перерисовать найденные треугольники другим цветом.
- Сохранить координаты и узлы этих треугольников в файл.
Исходный рисунок:
Входные данные:
Координаты (coord.txt)
3 4 5 4 3 2 1 2 3 4 3 2 3
5 4 3 2 1 2 3 4 4 3 2 3 3
Вершины (tops.txt)
16 //число вершин для задания размерности массива;
1 9 2
2 9 10
3 2 10
4 3 10
4 10 11
5 4 11
6 5 11
6 11 12
6 12 7
7 12 8
8 12 9
9 1 8
10 9 13
11 10 13
12 11 13
13 9 12
Полученный рисунок:
Выходные данные:
Координаты (new_coord.txt)
2: (4, 4) (3, 4) (4, 3)
5: (4, 2) (4, 3) (3, 2)
8: (2, 2) (3, 2) (2, 3)
11: (2, 4) (2, 3) (3, 4)
13: (4, 3) (3, 4) (3, 3)
14: (3, 2) (4, 3) (3, 3)
15: (2, 3) (3, 2) (3, 3)
16: (3, 3) (3, 4) (2, 3)
Вершины (new_tops.txt)
2: 2 9 10
5: 4 10 11
8: 6 11 12
11: 8 12 9
13: 10 9 13
14: 11 10 13
15: 12 11 13
16: 13 9 12
Исходный код:
exec.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace course_work
{
class exec
{
//Массивы координат и номеров вершин треугольников
static public double[] x = null;
static public double[] y = null;
static public int[,] triangles = null;
//Метод считывания данных из файлов
static public void ReadData(string Coord_path, string Tops_path)
{
StreamReader coord = new StreamReader(Coord_path);
StreamReader tops = new StreamReader(Tops_path);
char filter = ‘ ‘;
//Считывание координат, запись в два массива X и Y
string[] line1 = coord.ReadLine().Split(filter);
string[] line2 = coord.ReadLine().Split(filter);
x = new double[line1.Length];
y = new double[line2.Length];
for (int n = 0; n < line1.Length; n++)
{
x[n] = int.Parse(line1[n]);
y[n] = int.Parse(line2[n]);
}
//Считывание номеров вершин, запись в массив треугольников
int size1 = int.Parse(tops.ReadLine());
triangles = new int[size1, 3];
int i = 0;
for (string L = tops.ReadLine(); L != null; L = tops.ReadLine())
{
string[] subS = L.Split(filter);
for (int j = 0; j < subS.Length; j++)
triangles[i, j] = int.Parse(subS[j]);
i++;
}
}
static public int[] Internal = null;
//Метод анализа внутренних треугольников
static public void Analyze(string Coord_p, string Tops_p)
{
ReadData(Coord_p, Tops_p);
bool[,] num = new bool[triangles.GetLength(0), 3];
int t1, t2;
int c = 0;
for (int i = 0; i < triangles.GetLength(0); i++)
{
for (int j = 0; j < 3; j++)
{
t1 = triangles[i, j];
t2 = triangles[i, (j + 1) % 3];
for (int m = 1 + i; m < triangles.GetLength(0); m++)
{
for (int k = 0; k < 3; k++)
if (t1 == triangles[m, (k + 1) % 3] && t2 == triangles[m, k])
{
num[i, j] = true;
num[m, k] = true;
}
}
}
if (num[i, 0] == true && num[i, 1] == true && num[i, 2] == true)
c++;
}
Internal = new int;
int n = 0;
for (int i = 0; i < num.GetLength(0); i++)
if (num[i, 0] == true && num[i, 1] == true && num[i, 2] == true)
{
Internal[n] = i;
n++;
}
}
//Метод записи в файл координат и узлов
static public void WriteData(string NewCoord, string NewTops, string PathC, string PathT)
{
Analyze(PathC, PathT);
StreamWriter NewC = new StreamWriter(NewCoord);
StreamWriter NewT = new StreamWriter(NewTops);
int n = 0;
for (int i = 0; i < Internal.Length; i++)
{
n = Internal[i];
NewC.Write(«{0}: «, n + 1);
for (int j = 0; j < 3; j++)
NewC.Write(«({0}, {1}) «, x[triangles[n, j] — 1], y[triangles[n, j] — 1]);
NewC.WriteLine();
}
NewC.Close();
for (int i = 0; i < Internal.Length; i++)
{
n = Internal[i];
NewT.Write(«{0}: «, n+1);
for (int j = 0; j < 3; j++)
NewT.Write(«{0} «, triangles[n, j]);
NewT.WriteLine();
}
NewT.Close();
}
}
}
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
namespace course_work
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
private void FormMain_Load(object sender, EventArgs e)
{
}
//Пути к файлам с координатами и вершинами
string Path1 = @»c:\users\администратор\documents\visual studio 2010\Projects\курсовая\course_work\coord.txt»;
string Path2 = @»c:\users\администратор\documents\visual studio 2010\Projects\курсовая\course_work\tops.txt»;
string NewPath1 = @»c:\users\администратор\desktop\new_coord.txt»;
string NewPath2 = @»c:\users\администратор\desktop\new_tops.txt»;
private void DrawingSpace_Paint(object sender, PaintEventArgs e)
{
//Создание графических инструментов, линий двух разных цветов и шрифта для подписей узлов
Graphics g = e.Graphics;
Pen p = new Pen(Color.DarkCyan, 3);
Pen pI = new Pen(Color.AliceBlue, 4);
Pen pE = new Pen(Color.DarkCyan, 6);
Font F = new Font(«ComicSansMS», 10);
SolidBrush Brush = new SolidBrush(Color.LawnGreen);
GraphicsPath graph = new GraphicsPath();
exec.ReadData(Path1, Path2);
//Задание размерности поля рисования и смещения, перевод координат
int L = 400;
int H = 400;
int shift = 50;
double x_max = exec.x.Max(), y_max = exec.y.Max();
double x_min = exec.x.Min(), y_min = exec.y.Min();
double Lr = x_max — x_min;
double Hr = y_max — y_min;
//Первоначальная отрисовка треугольников
for (int i = 0; i < exec.triangles.GetLength(0); i++)
{
int a = exec.triangles[i, 0];
int b = exec.triangles[i, 1];
int c = exec.triangles[i, 2];
int xa = (int)(((exec.x[a — 1] — x_min) / Lr) * L) + shift;
int xb = (int)(((exec.x[b — 1] — x_min) / Lr) * L) + shift;
int xc = (int)(((exec.x — x_min) / Lr) * L) + shift;
int ya = (int)((1 — (exec.y[a — 1] — y_min) / Hr) * H) + shift;
int yb = (int)((1 — (exec.y[b — 1] — y_min) / Hr) * H) + shift;
int yc = (int)((1 — (exec.y — y_min) / Hr) * H) + shift;
Point A = new Point(xa, ya);
Point B = new Point(xb, yb);
Point C = new Point(xc, yc);
g.DrawLine(p, A, B);
g.DrawLine(p, B, C);
g.DrawLine(p, C, A);
}
//Закрашивание внутренних треугольников
exec.Analyze(Path1, Path2);
int n = 0;
for (int i = 0; i < exec.Internal.Length; i++)
{
n = exec.Internal[i];
int a = exec.triangles[n, 0];
int b = exec.triangles[n, 1];
int c = exec.triangles[n, 2];
int xa = (int)(((exec.x[a — 1] — x_min) / Lr) * L) + shift;
int xb = (int)(((exec.x[b — 1] — x_min) / Lr) * L) + shift;
int xc = (int)(((exec.x — x_min) / Lr) * L) + shift;
int ya = (int)((1 — (exec.y[a — 1] — y_min) / Hr) * H) + shift;
int yb = (int)((1 — (exec.y[b — 1] — y_min) / Hr) * H) + shift;
int yc = (int)((1 — (exec.y — y_min) / Hr) * H) + shift;
Point A = new Point(xa, ya);
Point B = new Point(xb, yb);
Point C = new Point(xc, yc);
graph.AddLine(B, A);
g.FillPath(Brush, graph);
g.DrawLine(pI, A, B);
g.DrawLine(pI, B, C);
g.DrawLine(pI, C, A);
}
for (int i = 0; i < exec.triangles.GetLength(0); i++)
{
int a = exec.triangles[i, 0];
int xa = (int)(((exec.x[a — 1] — x_min) / Lr) * L) + shift;
int ya = (int)((1 — (exec.y[a — 1] — y_min) / Hr) * H) + shift;
Point A = new Point(xa + 5, ya + 5);
g.DrawString((exec.triangles[i, 0]).ToString(), F, Brushes.Black, A);
g.DrawEllipse(pE, xa — 2, ya — 2, 5, 5);
}
}
//Кнопка сохранения
private void SaveB_Click(object sender, EventArgs e)
{
exec.WriteData(NewPath1, NewPath2, Path1, Path2);
label3.Text = «Успешно сохранено»;
}
//Кнопка выхода
private void ExitB_Click(object sender, EventArgs e)
{
Close();
}