Нахождение внутренних треугольников в сетке — C(Си)

Задание:

  1. Задать фигуру, имеющую внутренние и внешние треугольники.
  2. Создать файлы, в которых будут записаны координаты вершин и узлы треугольников.
  3. Реализовать программно чтение данных из файла и конвертацию их в числовые массивы координат и треугольников.
  4. Преобразовать координаты из естественной в экранную систему координат.
  5. Нарисовать полученную фигуру.
  6. Выполнить анализ и найти внутренние треугольники.
  7. Перерисовать найденные треугольники другим цветом.
  8. Сохранить координаты и узлы этих треугольников в файл.

Исходный рисунок:

Входные данные:

Координаты (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();

}

Leave a Comment