Advertisement
Guest User

Untitled

a guest
Nov 21st, 2019
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.37 KB | None | 0 0
  1. #pragma once
  2.  
  3. namespace stepanova {
  4.     using namespace System;
  5.     using namespace System::ComponentModel;
  6.     using namespace System::Collections;
  7.     using namespace System::Windows::Forms;
  8.     using namespace System::Data;
  9.     using namespace System::Drawing;
  10.     using namespace std;
  11.  
  12.     float Vx; // размер рисунка по горизонтали
  13.     float Vy; // размер рисунка по вертикали
  14.     float aspectFig; // соотношение сторон рисунка
  15.     vector<path> figure;
  16.     mat3 T; // матрица, в которой накапливаются все преобразования
  17.     mat3 initT; // матрица начального преобразования
  18.  
  19.     /// <summary>
  20.     /// Сводка для MyForm
  21.     /// </summary>
  22.     public ref class MyForm : public System::Windows::Forms::Form
  23.     {
  24.     public:
  25.         MyForm(void)
  26.         {
  27.             InitializeComponent();
  28.             //
  29.             //TODO: добавьте код конструктора
  30.             //
  31.         }
  32.  
  33.     protected:
  34.         /// <summary>
  35.         /// Освободить все используемые ресурсы.
  36.         /// </summary>
  37.         ~MyForm()
  38.         {
  39.             if (components)
  40.             {
  41.                 delete components;
  42.             }
  43.         }
  44.     private: System::Windows::Forms::OpenFileDialog^ openFileDialog;
  45.     private: System::Windows::Forms::Button^ btnOpen;
  46.     protected:
  47.  
  48.  
  49.     protected:
  50.  
  51.     private:
  52.         /// <summary>
  53.         /// Обязательная переменная конструктора.
  54.         /// </summary>
  55.         System::ComponentModel::Container^ components;
  56.  
  57. #pragma region Windows Form Designer generated code
  58.         /// <summary>
  59.         /// Требуемый метод для поддержки конструктора — не изменяйте
  60.         /// содержимое этого метода с помощью редактора кода.
  61.         /// </summary>
  62.         void InitializeComponent(void)
  63.         {
  64.             this->openFileDialog = (gcnew System::Windows::Forms::OpenFileDialog());
  65.             this->btnOpen = (gcnew System::Windows::Forms::Button());
  66.             this->SuspendLayout();
  67.             //
  68.             // openFileDialog
  69.             //
  70.             this->openFileDialog->DefaultExt = L"txt";
  71.             this->openFileDialog->Filter = L"Текстовые файлы (*.txt)|*.txt|Все файлы (*.*)|*.*";
  72.             this->openFileDialog->Title = L"Открыть файл";
  73.             //
  74.             // btnOpen
  75.             //
  76.             this->btnOpen->Location = System::Drawing::Point(12, 12);
  77.             this->btnOpen->Name = L"btnOpen";
  78.             this->btnOpen->Size = System::Drawing::Size(116, 37);
  79.             this->btnOpen->TabIndex = 0;
  80.             this->btnOpen->Text = L"Открыть";
  81.             this->btnOpen->UseVisualStyleBackColor = true;
  82.             this->btnOpen->Click += gcnew System::EventHandler(this, &MyForm::btnOpen_Click);
  83.             //
  84.             // MyForm
  85.             //
  86.             this->AutoScaleDimensions = System::Drawing::SizeF(8, 16);
  87.             this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
  88.             this->ClientSize = System::Drawing::Size(518, 257);
  89.             this->Controls->Add(this->btnOpen);
  90.             this->DoubleBuffered = true;
  91.             this->KeyPreview = true;
  92.             this->Margin = System::Windows::Forms::Padding(4);
  93.             this->Name = L"MyForm";
  94.             this->Text = L"MyForm";
  95.             this->Load += gcnew System::EventHandler(this, &MyForm::MyForm_Load);
  96.             this->Paint += gcnew System::Windows::Forms::PaintEventHandler(this, &MyForm::MyForm_Paint);
  97.             this->KeyDown += gcnew System::Windows::Forms::KeyEventHandler(this, &MyForm::MyForm_KeyDown);
  98.             this->Resize += gcnew System::EventHandler(this, &MyForm::MyForm_Resize);
  99.             this->ResumeLayout(false);
  100.  
  101.         }
  102. #pragma endregion
  103.  
  104.     private: System::Void MyForm_Load(System::Object^ sender, System::EventArgs^ e) {
  105.     }
  106.  
  107.     private: System::Void MyForm_Paint(System::Object^ sender, System::Windows::Forms::PaintEventArgs^ e) {
  108.         Graphics^ g = e->Graphics;
  109.         g->Clear(Color::FloralWhite);
  110.  
  111.         for (int i = 0; i < figure.size(); i++) {
  112.             path lines = figure[i]; // lines - очередная ломаная линия
  113.             Pen^ pen = gcnew Pen(Color::FromArgb(lines.color.x, lines.color.y, lines.color.z));
  114.             pen->Width = lines.thickness;
  115.  
  116.             vec2 start = normalize(T * vec3(lines.vertices[0], 1.0)); // начальная точка первого отрезка
  117.             for (int j = 1; j < lines.vertices.size(); j++) { // цикл по конечным точкам (от единицы)
  118.                 vec2 end = normalize(T * vec3(lines.vertices[j], 1.0)); // конечная точка
  119.                 g->DrawLine(pen, start.x, start.y, end.x, end.y); // отрисовка отрезка
  120.                 start = end; // конечная точка текущего отрезка становится начальной точкой следующего
  121.             }
  122.         }
  123.     }
  124.  
  125.     private: System::Void MyForm_Resize(System::Object^ sender, System::EventArgs^ e) {
  126.         Refresh();
  127.     }
  128.  
  129.     private: System::Void MyForm_KeyDown(System::Object^ sender, System::Windows::Forms::KeyEventArgs^ e) {
  130.         float Wcx = ClientRectangle.Width / 2.f; // координаты центра
  131.         float Wcy = ClientRectangle.Height / 2.f; // текущего окна
  132.         switch (e->KeyCode) {
  133.         case Keys::Escape:
  134.             T = initT;
  135.             break;
  136.         case Keys::Q:
  137.             T = translate(-Wcx, -Wcy) * T; // перенос начала координат в (Wcx, Wcy)
  138.             T = rotate(0.01f) * T; // поворот на 0.01 радиан относительно
  139.             // нового центра
  140.             T = translate(Wcx, Wcy) * T; // перенос начала координат обратно
  141.             break;
  142.         case Keys::E:
  143.             T = translate(-Wcx, -Wcy) * T; // перенос начала координат в (Wcx, Wcy)
  144.             T = rotate(-0.01f) * T; // поворот на 0.01 радиан относительно
  145.             // нового центра
  146.             T = translate(Wcx, Wcy) * T; // перенос начала координат обратно
  147.             break;
  148.         case Keys::R:
  149.             T = translate(-Wcx, -Wcy) * T; // перенос начала координат в (Wcx, Wcy)
  150.             T = rotate(-0.05f) * T; // поворот на 0.01 радиан относительно
  151.             // нового центра
  152.             T = translate(Wcx, Wcy) * T; // перенос начала координат обратно
  153.             break;
  154.         case Keys::Y:
  155.             T = translate(-Wcx, -Wcy) * T; // перенос начала координат в (Wcx, Wcy)
  156.             T = rotate(0.05f) * T; // поворот на 0.01 радиан относительно
  157.             // нового центра
  158.             T = translate(Wcx, Wcy) * T; // перенос начала координат обратно
  159.             break;
  160.         case Keys::W:
  161.             T = translate(0.f, -1.f) * T; // сдвиг вверх на один пиксел
  162.             break;
  163.         case Keys::S:
  164.             T = translate(0.f, 1.f) * T; // сдвиг вниз на один пиксел
  165.             break;
  166.         case Keys::A:
  167.             T = translate(-1.f, -0.f) * T; // сдвиг влево на один пиксел
  168.             break;
  169.         case Keys::D:
  170.             T = translate(1.f, 0.f) * T; // сдвиг вправо на один пиксел
  171.             break;
  172.         case Keys::T:
  173.             T = translate(0.f, -10.f) * T; // сдвиг вверх на один пиксел
  174.             break;
  175.         case Keys::G:
  176.             T = translate(0.f, 10.f) * T; // сдвиг вниз на один пиксел
  177.             break;
  178.         case Keys::F:
  179.             T = translate(-10.f, -0.f) * T; // сдвиг влево на один пиксел
  180.             break;
  181.         case Keys::H:
  182.             T = translate(10.f, 0.f) * T; // сдвиг вправо на один пиксел
  183.             break;
  184.         case Keys::Z:
  185.             T = translate(-Wcx, -Wcy) * T;
  186.             T = scale(1.1) * T;
  187.             T = translate(Wcx, Wcy) * T;
  188.             break;
  189.         case Keys::X:
  190.             T = translate(-Wcx, -Wcy) * T;
  191.             T = scale(1.0 / 1.1) * T;
  192.             T = translate(Wcx, Wcy) * T;
  193.             break;
  194.         case Keys::U:
  195.             T = translate(-Wcx, -Wcy) * T;
  196.             T = mirrorX() * T;
  197.             T = translate(Wcx, Wcy) * T;
  198.             break;
  199.         case Keys::J:
  200.             T = translate(-Wcx, -Wcy) * T;
  201.             T = mirrorY() * T;
  202.             T = translate(Wcx, Wcy) * T;
  203.             break;
  204.         case Keys::I:
  205.             T = translate(-Wcx, -Wcy) * T;
  206.             T = scale(1.1, 1.0) * T;
  207.             T = translate(Wcx, Wcy) * T;
  208.             break;
  209.         case Keys::K:
  210.             T = translate(-Wcx, -Wcy) * T;
  211.             T = scale(1.0 / 1.1 , 1.0) * T;
  212.             T = translate(Wcx, Wcy) * T;
  213.             break;
  214.         case Keys::O:
  215.             T = translate(-Wcx, -Wcy) * T;
  216.             T = scale(1.0, 1.1) * T;
  217.             T = translate(Wcx, Wcy) * T;
  218.             break;
  219.         case Keys::L: //Сжатие относительно центра по оси Y
  220.             T = translate(-Wcx, -Wcy) * T;
  221.             T = scale(1.0, 1.0 / 1.1) * T;
  222.             T = translate(Wcx, Wcy) * T;
  223.             break;
  224.         default:
  225.             break;
  226.         }
  227.         Refresh();
  228.     }
  229.  
  230.     private: System::Void btnOpen_Click(System::Object^ sender, System::EventArgs^ e) {
  231.         if (openFileDialog->ShowDialog() == System::Windows::Forms::DialogResult::OK) {
  232.             // в файловом диалоге нажата кновка OK
  233.                 // перезапись имени файла из openFileDialog->FileName в fileName
  234.             wchar_t fileName[1024]; // переменная, в которой посимвольно сохраним имя файла
  235.             for (int i = 0; i < openFileDialog->FileName->Length; i++)
  236.                 fileName[i] = openFileDialog->FileName[i];
  237.             fileName[openFileDialog->FileName->Length] = '\0';
  238.  
  239.             // объявление и открытие файла
  240.             ifstream in;
  241.             in.open(fileName);
  242.             if (in.is_open()) {
  243.                 // файл успешно открыт
  244.                 figure.clear(); // очищаем имеющийся список ломаных
  245.             // временные переменные для чтения из файла
  246.                 float thickness = 2; // толщина со значением по умолчанию 2
  247.                 float r, g, b; // составляющие цвета
  248.                 r = g = b = 0; // значение составляющих цвета по умолчанию (черный)
  249.                 string cmd; // строка для считывания имени команды
  250.                 // непосредственно работа с файлом
  251.                 string str; // строка, в которую считываем строки файла
  252.                 getline(in, str); // считываем из входного файла первую строку
  253.                 while (in) { // если очередная строка считана успешно
  254.                     // обрабатываем строку
  255.                     if ((str.find_first_not_of(" \t\r\n") != string::npos) && (str[0] != '#')) {
  256.                         // прочитанная строка не пуста и не комментарий
  257.                         stringstream s(str); // строковый поток из строки str
  258.                         s >> cmd;
  259.                         if (cmd == "frame") { // размеры изображения
  260.                             s >> Vx >> Vy; // считываем глобальные значение Vx и Vy
  261.                             aspectFig = Vx / Vy; // обновление соотношения сторон
  262.                             float Wx = ClientRectangle.Width; // размер окна по горизонтали
  263.                             float Wy = ClientRectangle.Height; // размер окна по вертикали
  264.                             float aspectForm = Wx / Wy; // соотношение сторон окна рисования
  265.                             // коэффициент увеличения при сохранении исходного соотношения сторон
  266.                             float S = aspectFig < aspectForm ? Wy / Vy : Wx / Vx;
  267.                             float Ty = S * Vy; // смещение в положительную сторону по оси Oy после смены знака
  268.                             initT = translate(0.f, Ty) * scale(S, -S); // преобразования применяются справа налево
  269.                             // сначала масштабирование, а потом перенос
  270.                                 // в initT совмещаем эти два преобразования
  271.                             T = initT;
  272.                         }
  273.                         else if (cmd == "color") { // цвет линии
  274.                             s >> r >> g >> b; // считываем три составляющие цвета
  275.                         }
  276.                         else if (cmd == "thickness") { // толщина линии
  277.                             s >> thickness; // считываем значение толщины
  278.                         }
  279.                         else if (cmd == "path") { // набор точек
  280.                             vector<vec2> vertices; // список точек ломаной
  281.                             int N; // количество точек
  282.                             s >> N;
  283.                             string str1; // дополнительная строка для чтения из файла
  284.                             while (N > 0) { // пока не все точки считали
  285.                                 getline(in, str1); // считываем в str1 из входного файла очередную строку
  286.                                 // так как файл корректный, то на конец файла проверять не нужно
  287.                                 if ((str1.find_first_not_of(" \t\r\n") != string::npos) && (str1[0] != '#')) {
  288.                                     // прочитанная строка не пуста и не комментарий
  289.                                         // значит в ней пара координат
  290.                                     float x, y; // переменные для считывания
  291.                                     stringstream s1(str1); // еще один строковый поток из строки str1
  292.                                     s1 >> x >> y;
  293.                                     vertices.push_back(vec2(x, y)); // добавляем точку в список
  294.                                     N--; // уменьшаем счетчик после успешного считывания точки
  295.                                 }
  296.                             }
  297.                             // все точки считаны, генерируем ломаную (path) и кладем ее в список figure
  298.                             figure.push_back(path(vertices, vec3(r, g, b), thickness));
  299.                         }
  300.                     }
  301.                     // считываем очередную строку
  302.                     getline(in, str);
  303.                 }
  304.                 Refresh();
  305.             }
  306.         }
  307.     }
  308.     };
  309. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement