laba 1
.docxМИНИСТЕРСТВО ЦИФРОВОГО РАЗВИТИЯ, СВЯЗИ И МАССОВЫХ КОММУНИКАЦИЙ РОССИЙСКОЙ ФЕДЕРАЦИИ
ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ
«САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ТЕЛЕКОММУНИКАЦИЙ ИМ.ПРОФ.М.А.БОНЧ-БРУЕВИЧА»
(СПбГУТ)
Факультет: «Институт магистратуры»
Кафедра: «Систем автоматизации и робототехники»
Направление подготовки: |
Автоматизация технологических процессов и производств |
Направленность (профиль): |
Интеллектуальные технологии в автоматизации |
ЛАБОРАТОРНАЯ РАБОТА № 1
по дисциплине:
Автоматизированное проектирование средств и систем управления |
на тему:
Автомасштабирование
-
Выполнили студенты группы:
дата, подпись
Фамилия И. О.
Принял к.т.н., доцент
Чебыкин В.А.
дата, подпись
Фамилия И. О.
Задание: Реализовать автомасштабирование элементов
Ход работы
Программный код с выполненными заданиями:
namespace Osipenko_graph_work
{ //Мужики, ФПСОВ НЕТ СДЕЛАЙЕТЕ ЧТО НИТЬ
public partial class Form1 : Form
{
Graph graph = new Graph();
Graph graph2 = new Graph();
// Базовые размеры на котором изначально рисуются объекты. 709 на 419, но нужно уменьшить ширину
private const float designWidth = 700f;
private const float designHeight = 300f;
public Form1()
{
InitializeComponent();
// двойная буферизацию для ФПС
this.DoubleBuffered = true;
// Обработчик события изменения размера формы
this.Resize += Form1_Resize;
graph.Generate();
graph2.Copy(graph);
graph2.Move(300);
label1.Text = "Изменённый граф";
label2.Text = "Исходный граф";
label3.Text = "l: " + (int)graph.Length();
label4.Text = "l: " + (int)graph.Length();
}
// При изменении размеров окна перерисовываем форму
private void Form1_Resize(object sender, EventArgs e)
{
this.Invalidate();
}
// Обработчик отрисовки
private void Form1_Paint(object sender, PaintEventArgs e)
{
// Расчёт коэффициентов масштабирования
float scaleX = (float)ClientSize.Width / designWidth;
float scaleY = (float)ClientSize.Height / designHeight;
float scale = Math.Min(scaleX, scaleY);
// Применяем масштабирование
e.Graphics.ScaleTransform(scale, scale);
// Вычисляем размеры области
float virtualWidth = ClientSize.Width / scale;
float virtualHeight = ClientSize.Height / scale;
// Дополнительный отступ слева
float extraLeftMargin = 50f;
// Вычисляем смещения для позиционирования графа:
float offsetX = (virtualWidth - designWidth) / 2f + extraLeftMargin;
float offsetY = (virtualHeight - designHeight) / 2f;
e.Graphics.TranslateTransform(offsetX, offsetY);
// Отрисовка графов
graph.Draw(e.Graphics);
graph2.Draw(e.Graphics);
}
public class Graph
{
public List<PointGraph> pgsList = new List<PointGraph>();
public List<Line> linesList = new List<Line>();
public List<Line> lnList = new List<Line>();
int m = 0;
public void Generate()
{
pgsList.Clear();
linesList.Clear();
int n = 1;
Random offset_points_rand = new Random();
int offset_x = offset_points_rand.Next(50, 150);
int offset_y = offset_points_rand.Next(30, 50);
for (int i = 20; i <= 300; i += offset_x)
{
for (int j = 20; j <= 200; j += offset_y)
{
pgsList.Add(new PointGraph(i, j, n++, Brushes.White));
}
}
Random next_point_for_line_rand = new Random();
Random lines_weight_rand = new Random();
int next_line_point_offset = next_point_for_line_rand.Next(1, 5);
for (int point = 0; point <= pgsList.Count() - 2; point += next_line_point_offset)
{
Random lines_generate_rand = new Random();
int number_of_lines_from_point = lines_generate_rand.Next(1, 5);
int point_where_lines_is_going_on = lines_generate_rand.Next(1, 5);
int line_number = 0;
int weight = lines_weight_rand.Next(1, 5);
for (line_number = 0; line_number <= number_of_lines_from_point; line_number++)
{
linesList.Add(new Line(point, point_where_lines_is_going_on, weight, this));
}
}
}
public void AddLineToTree()
{
int count = pgsList.Count();
for (int i = 0; i < lnList.Count && m < count; i++)
{
if (pgsList[lnList[i].ind1].inTree == true &&
pgsList[lnList[i].ind2].inTree == true)
continue;
if (pgsList[lnList[i].ind1].inTree == true ||
pgsList[lnList[i].ind2].inTree == true)
{
pgsList[lnList[i].ind1].inTree = true;
pgsList[lnList[i].ind2].inTree = true;
linesList.Add(lnList[i]);
lnList.RemoveAt(i);
m++;
break;
}
}
}
public void Generate3()
{
pgsList.Clear();
lnList.Clear();
linesList.Clear();
int n = 1;
Random offset_points_rand = new Random();
int offset_x = offset_points_rand.Next(50, 150);
int offset_y = offset_points_rand.Next(30, 50);
Random ran3 = new Random();
for (int i = 20; i <= 300; i += offset_x)
{
for (int j = 20; j <= 200; j += offset_y)
{
int r3 = ran3.Next(0, 4);
if (r3 >= 2)
pgsList.Add(new PointGraph(i, j, n++, Brushes.White));
}
}
int count = pgsList.Count();
for (int i = 0; i < count-1; i++)
{
PointGraph p1 = pgsList[i];
for(int k = i+1; k < count; k++)
{
PointGraph p2 = pgsList[k];
Line ln = new Line(i, k, 1, this);
lnList.Add(ln);
}
}
lnList.Sort(CompareLineLength);
m = 0;
pgsList[lnList[0].ind1].inTree = true;
pgsList[lnList[0].ind2].inTree = true;
linesList.Add(lnList[0]);
lnList.RemoveAt(0);
m++;
}
private static int CompareLineLength(Line x, Line y)
{
return x.l.CompareTo( y.l);
}
public void Draw(Graphics gr)
{
foreach (Line line in linesList)
{
line.Draw(gr);
}
foreach (PointGraph pg in pgsList)
{
pg.Draw(gr);
}
}
public double Length()
{
double l2 = 0;
foreach (Line line in linesList)
{
l2 += line.l;
}
return l2;
}
public void Swap(int i, int k)
{
int x = 0;
int y = 0;
x = pgsList[i].x;
y = pgsList[i].y;
pgsList[i].x = pgsList[k].x;
pgsList[i].y = pgsList[k].y;
pgsList[k].x = x;
pgsList[k].y = y;
}
public void Green(int i, int k)
{
pgsList[i].brush = Brushes.Green;
pgsList[k].brush = Brushes.Green;
}
public void Repaint(Brush brushnew, Brush brushold)
{
for (int i = 0; i < pgsList.Count; i++)
{
if (pgsList[i].brush == brushold)
pgsList[i].brush = brushnew;
}
}
public void Copy(Graph graph)
{
pgsList.Clear();
linesList.Clear();
foreach (PointGraph v in graph.pgsList)
{
PointGraph v1 = new PointGraph(v.x, v.y, v.name, v.brush);
this.pgsList.Add(v1);
}
foreach (Line line in graph.linesList)
{
Line line1 = new Line(line.ind1, line.ind2, line.weight, this);
this.linesList.Add(line1);
}
}
public void Move(int dx, int dy = 0)
{
foreach (PointGraph pg in pgsList)
{
pg.x += dx;
pg.y += dy;
}
}
public int GetLinesCount(int ind)
{
int lCount = 0;
foreach (Line line in linesList)
{
if ((line.ind1 == ind) || (line.ind2 == ind))
{
lCount++;
}
}
return lCount;
}
public void MoveIntoCenter()
{
int mx = 0;
int ind_mx = 0;
for (int i = 0; i <= pgsList.Count(); i++)
{
if (GetLinesCount(i) > mx)
{
mx = GetLinesCount(i);
ind_mx = i;
}
}
PointGraph temp_pg = pgsList[ind_mx];
int center = pgsList.Count() / 2;
pgsList[ind_mx] = pgsList[center];
pgsList[center] = temp_pg;
}
}
public class PointGraph
{
public bool inTree;
public int name;
public int x, y;
public Brush brush;
public PointGraph(int x, int y, int name, Brush brush)
{
inTree = false;
this.x = x;
this.y = y;
this.name = name;
this.brush = brush;
}
public void Draw(Graphics gr)
{
gr.FillEllipse(brush, new Rectangle(x - 10, y - 10, 20, 20));
gr.DrawString(name.ToString(), SystemFonts.DefaultFont, Brushes.Black, new Point(x - 10, y - 10));
}
}
public class Line
{
public int ind1, ind2;
protected Graph lgraph;
public int weight;
public double l
{
get
{
return Math.Sqrt(((lgraph.pgsList[ind1].x - lgraph.pgsList[ind2].x) * (lgraph.pgsList[ind1].x - lgraph.pgsList[ind2].x)) + ((lgraph.pgsList[ind1].y - lgraph.pgsList[ind2].y) * (lgraph.pgsList[ind1].y - lgraph.pgsList[ind2].y)));
}
}
public Line(int ind1, int ind2, int weight, Graph lgraph)
{
int count = lgraph.pgsList.Count;
if (ind1 < count)
this.ind1 = ind1;
else
this.ind1 = 0;
if (ind2 < count)
this.ind2 = ind2;
else
this.ind2 = 0;
this.weight = weight;
this.lgraph = lgraph;
}
public void Draw(Graphics gr)
{
gr.DrawLine(new Pen(Brushes.Black, weight), new Point(lgraph.pgsList[ind1].x, lgraph.pgsList[ind1].y), new Point(lgraph.pgsList[ind2].x, lgraph.pgsList[ind2].y));
}
}
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
double length_before = (int)graph.Length();
Random rand = new Random();
int i = rand.Next(0, graph.pgsList.Count() - 1);
int k = rand.Next(0, graph.pgsList.Count() - 1);
graph.Swap(i, k);
double length_after = (int)graph.Length();
if (length_after > length_before)
{
graph.Swap(k, i);
label3.Text = "l: " + length_before.ToString();
}
else
{
graph.Green(i, k);
label3.Text = "l: " + length_after.ToString();
}
button1.Visible = true;
Invalidate();
}
private void button1_Click(object sender, EventArgs e)
{
graph.MoveIntoCenter();
button1.Visible = true;
Invalidate();
}
private void button2_Click(object sender, EventArgs e)
{
graph.Generate();
graph2.Copy(graph);
graph2.Move(300);
label3.Text = "l: " + (int)graph.Length();
label4.Text = "l: " + (int)graph.Length();
Invalidate();
}
private void button3_Click(object sender, EventArgs e)
{
graph.Repaint(Brushes.White, Brushes.Green);
Invalidate();
}
private void button4_Click(object sender, EventArgs e)
{
graph.Generate3();
graph2.Copy(graph);
graph2.Move(300);
label3.Text = "l: " + (int)graph.Length();
label4.Text = "l: " + (int)graph.Length();
Invalidate();
}
private void button5_Click(object sender, EventArgs e)
{
graph.AddLineToTree();
Invalidate();
}
}
}
Результат компиляции:
Стартовый размер окна 709px на 419px
Полный экран 1920px на 1080px
Вывод: Мы научились автомасштабировать элементы интерфейса под экран пользователя
Санкт Петербург
2025
