Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Matrix.h
- #pragma once
- // ВЕКТОРА
- class vec2
- {
- public:
- float x, y;
- // конструкторы
- vec2() {}
- vec2(float a, float b) : x(a), y(b) {}
- // перегурзка операций умножения и адресации по индексу
- vec2& operator *= (const vec2& v)
- {
- x *= v.x;
- y *= v.y;
- return *this;
- }
- const vec2 operator * (const vec2& v)
- {
- return vec2(*this) *= v;
- }
- float& operator [] (int i)
- {
- return ((float*)this)[i];
- }
- };
- // скалярное умножение
- float dot(vec2 v1, vec2 v2)
- {
- vec2 tmp = v1 * v2; // вычисляем произведения соответствующих координат
- return tmp.x + tmp.y; // и возвращаем их сумму
- }
- class vec3
- {
- public:
- float x, y, z;
- // конструкторы
- vec3() {}
- vec3(float a, float b, float c) : x(a), y(b), z(c) {}
- vec3(vec2 v, float z) : vec3(v.x, v.y, z) {}
- // перегрузка операций *= , * и []
- vec3& operator *= (const vec3& v)
- {
- x *= v.x;
- y *= v.y;
- z *= v.z;
- return *this;
- }
- const vec3 operator * (const vec3& v)
- {
- return vec3(*this) *= v; // делаем временную копию текущего объекта, которую
- } // домножаем на данный вектор, и возвращаем ее как результат
- float& operator [] (int i)
- {
- return ((float*)this)[i]; // ссылку на текующий объект рассматриваем как ссылку на 0-ой элемент
- } // массива значений типа float, после чего обращаемся к его i-ому элементу
- };
- // скалярное умножение
- float dot(vec3 v1, vec3 v2)
- {
- vec3 tmp = v1 * v2; // вычисляем произведение соответствующих координат
- return tmp.x + tmp.y + tmp.z; // и возвращаем их сумму
- }
- vec2 normalize(vec3 v)
- {
- return vec2(v.x / v.z, v.y / v.z);
- }
- class vec4
- {
- public:
- float x, y, z, a;
- // конструкторы
- vec4() {}
- vec4(float a, float b, float c, float d) : x(a), y(b), z(c), a(d) {}
- vec4(vec3 v, float c) : vec4(v.x, v.y, v.z, c) {}
- // перегрузка операции умножения векторов
- vec4& operator*=(const vec4& v)
- {
- x *= v.x;
- y *= v.y;
- z *= v.z;
- a *= v.a;
- return *this;
- }
- const vec4 operator*(const vec4& v)
- {
- return vec4(*this) *= v; // делаем временную копию текущего объекта,
- // которую домножаем на данный вектор,
- // и возвращаем ее как результат
- }
- // перегрузка операции обращения по индексу
- float& operator[](int i)
- {
- return ((float*)this)[i]; // ссылку на текущий объект рассматриваем как ссылку
- // на нулевой элемент массива значений типа float,
- // после чего, обращаемся к его i-му элемент
- }
- };
- // скалярное умножение
- float dot(vec4 v1, vec4 v2)
- {
- vec4 tmp = v1 * v2; // вычисляем произведения соответствующих координат
- return tmp.x + tmp.y + tmp.z + tmp.a; // и возвращаем их сумму
- }
- vec3 normalize(vec4 v)
- {
- // делим первые три координаты на значение четвертой
- return vec3(v.x / v.a, v.y / v.a, v.z / v.a);
- }
- // МАТРИЦЫ
- class mat4
- {
- public:
- vec4 row1, row2, row3, row4;
- // конструкторы
- mat4(vec4 r1, vec4 r2, vec4 r3, vec4 r4) : row1(r1), row2(r2), row3(r3), row4(r4) {}
- mat4(float a)
- {
- row1 = vec4(a, 0.f, 0.f, 0.f);
- row2 = vec4(0.f, a, 0.f, 0.f);
- row3 = vec4(0.f, 0.f, a, 0.f);
- row4 = vec4(0.f, 0.f, 0.f, a);
- }
- mat4() {}
- // перегрузка операции []
- vec4& operator[](int i)
- {
- return ((vec4*)this)[i]; // массив значений типа vec4
- }
- // транспонирование матрицы
- mat4 transpose()
- {
- mat4 tmp(*this); // делаем временную копию матрицы
- for (int i = 0; i < 4; i++)
- for (int j = 0; j < 4; j++)
- (*this)[i][j] = tmp[j][i]; // заменяем элементы текущего объекта
- // из временной копии
- return *this;
- }
- // перегрузка операций умножения
- const vec4 operator* (const vec4& v)
- {
- vec4* res = new(vec4); // создаем новый вектор (для результата)
- for (int i = 0; i < 4; i++)
- (*res)[i] = dot((*this)[i], v); // i-й элемент вектора - скалярное произведение
- return *res;
- }
- mat4& operator *= (const mat4& m)
- {
- mat4 A(*this), B(m); // создаем копии исходных матриц
- B.transpose(); // транспонируем вторую матрицу
- for (int i = 0; i < 4; i++)
- (*this)[i] = A * B[i]; // в i-ю строку текущего объекта записываем
- // результат перемножения первой матрицы с i-й строкой
- // транспонированной матрицы,
- return (*this).transpose(); // транспонируем текущий объект, получаем результат
- }
- const mat4 operator* (const mat4& m)
- {
- return mat4(*this) *= m;
- }
- };
- class mat3
- {
- public:
- vec3 row1, row2, row3; // строки матрицы
- // конструкторы
- mat3() {}
- mat3(vec3 r1, vec3 r2, vec3 r3) : row1(r1), row2(r2), row3(r3) {}
- mat3(float a) // диагональная матрица
- {
- row1 = vec3(a, 0.f, 0.f);
- row2 = vec3(0.f, a, 0.f);
- row3 = vec3(0.f, 0.f, a);
- }
- // перегрузка операции []
- vec3& operator [] (int i)
- {
- return ((vec3*)this)[i]; // массив значений типа vec3
- }
- // транспонирование матрицы
- mat3 transpose()
- {
- mat3 tmp(*this); // временная копия матрицы
- for (int i = 0; i < 3; ++i)
- for (int j = 0; j < 3; ++j)
- (*this)[i][j] = tmp[j][i]; // заменяем элементы текущего объекта
- // из временной копии
- return *this;
- }
- // перегрузка оператора *
- const vec3 operator * (const vec3& v)
- {
- vec3* res = new(vec3); // создаем новый вектор-результат
- for (int i = 0; i < 3; ++i)
- (*res)[i] = dot((*this)[i], v); // i-ый элемент веткора - скалярное произведение
- return *res;
- }
- // перемножение матриц (*= и *)
- // 1. B -> B.transpose()
- // 2. С = A * B.transpose()
- // 3. С -> C.transpose()
- mat3& operator *= (const mat3& m)
- {
- mat3 A(*this), B(m); // копии исходных матриц
- B.transpose();
- for (int i = 0; i < 3; ++i)
- (*this)[i] = A * B[i]; // в i-ую строку текущего объекта записываем результат перемножения
- // 1-ой матрицы с i-ой строкой транспонированной матрицы
- return (*this).transpose(); // транспонируем и получаем ответ
- }
- const mat3 operator * (const mat3& m)
- {
- return mat3(*this) *= m;
- }
- // дополнительный конструктор
- mat3(mat4 m)
- {
- row1 = vec3(m.row1.x, m.row1.y, m.row1.z);
- row2 = vec3(m.row2.x, m.row2.y, m.row2.z);
- row3 = vec3(m.row3.x, m.row3.y, m.row3.z);
- }
- };
- class mat2
- {
- public:
- vec2 row1, row2;
- // конструкторы
- mat2(vec2 r1, vec2 r2) : row1(r1), row2(r2) {}
- mat2(float a)
- {
- row1 = vec2(a, 0.f);
- row2 = vec2(0.f, a);
- }
- mat2() {}
- // перегрузка операции []
- vec2& operator [] (int i)
- {
- return ((vec2*)this)[i]; // массив значений типа vec2
- }
- // операции для матриц:
- // транспонирование
- mat2 transpose()
- {
- mat2 tmp(*this); // делаем временную копию матрицы
- for (int i = 0; i < 2; ++i)
- for (int j = 0; j < 2; ++j)
- (*this)[i][j] = tmp[j][i]; // заменяем элементы текущего объекта
- // из временной копии
- return *this;
- }
- // перегрузка операции умножения
- const vec2 operator* (const vec2& v)
- {
- vec2* res = new(vec2); // создаем новый вектор (для результата)
- for (int i = 0; i < 2; i++)
- (*res)[i] = dot((*this)[i], v); // i-й элемент вектора - скалярное произведение
- return *res;
- }
- mat2& operator *= (const mat2& m)
- {
- mat2 A(*this), B(m); // создаем копии исходных матриц
- B.transpose(); // транспонируем вторую матрицу
- for (int i = 0; i < 2; i++)
- (*this)[i] = A * B[i]; // в i-ю строку текущего объекта записываем
- // результат перемножения первой матрицы с i-й строкой
- // транспонированной матрицы
- return (*this).transpose(); // транспонируем текущий объект, получаем результат
- }
- // допольнительный конструктор
- mat2(mat3 m)
- {
- row1 = vec2(m[0][0], m[0][1]);
- row2 = vec2(m[1][0], m[1][1]);
- }
- };
- // Transform.h
- #pragma once
- #include "Matrix.h"
- #include <math.h>
- // матрица переноса
- mat3 translate(float Tx, float Ty)
- {
- mat3* res = new mat3(1.f); // матрица-результат
- (*res)[0][2] = Tx; // поменяли значения
- (*res)[1][2] = Ty; // в последнем столбце
- return *res;
- }
- mat4 translate(float Tx, float Ty, float Tz)
- {
- mat4* res = new mat4(1.f); // матрица-результат
- (*res)[0][3] = Tx; // поменяли значения
- (*res)[1][3] = Ty; // в последнем столбце
- (*res)[2][3] = Tz;
- return *res;
- }
- // матрица масштабирования
- mat3 scale(float Sx, float Sy)
- {
- mat3* res = new mat3(1.f); // матрица-результат
- (*res)[0][0] = Sx; // поменяли значения
- (*res)[1][1] = Sy; // на главной диагонали
- return *res;
- }
- // перегрузка: Sx = Sy = S
- mat3 scale(float S) { return scale(S, S); }
- mat4 scale(float Sx, float Sy, float Sz)
- {
- mat4* res = new mat4(1.f); // матрица-результат
- (*res)[0][0] = Sx; // поменяли значения
- (*res)[1][1] = Sy; // на главной диагонали
- (*res)[2][2] = Sz;
- return *res;
- }
- // матрица поворота (относительно начала координат против часовой стрелки)
- mat3 rotate(float theta)
- {
- mat3* res = new mat3(1.f); // матрица-результат
- (*res)[0][0] = (*res)[1][1] = (float)cos(theta); // заполнили главную диагональ
- (*res)[0][1] = (float)sin(theta); // синус в 1-ой строке (с плюсом)
- (*res)[1][0] = -(float)sin(theta); // синус во 2-ой строке (с минусом)
- return *res;
- }
- // матрица зеркального отображения относительно оси Ox
- mat3 mirrorX()
- {
- mat3* res = new mat3(1.f);
- (*res)[1][1] = -1.f;
- return *res;
- }
- // матрица зеркального отображения относительно оси Oy
- mat3 mirrorY()
- {
- mat3* res = new mat3(1.f);
- (*res)[0][0] = -1.f;
- return *res;
- }
- // Clip.h
- #pragma once
- #include "Matrix.h"
- #include <algorithm>
- using namespace std;
- // АЛГОРИТМ КОЭНА-САЗЕРЛЕНДА
- // Код точки: XXXX (0000 - область видимости)
- // 1 - выше; 0 - иначе
- // 1 - ниже; 0 - иначе
- // 1 - правее; 0 - иначе
- // 1 - левее; 0 - иначе
- // 1001 | 1000 | 1010
- // --------------------
- // 0001 | 0000 | 0010
- // --------------------
- // 0101 | 0100 | 0110
- // Код точки
- unsigned int codeKS(vec2 P, float minX, float minY, float maxX, float maxY)
- {
- unsigned int code = 0; // возращаемый результат
- if (P.x < minX) // слева
- code += 1;
- else if (P.x > maxX) // справа
- code += 2;
- if (P.y < minY) // ниже
- code += 4;
- else if (P.y > maxY) // выше
- code += 8;
- return code;
- }
- // Отсечение отрезка AB областью, заданной параметрами minX, minY, maxX, maxY
- // false - отрезок полностью невидим; true - в противном случае
- bool clip(vec2& A, vec2& B, float minX, float minY, float maxX, float maxY)
- {
- // находим коды точек A и B
- unsigned int codeA = codeKS(A, minX, minY, maxX, maxY);
- unsigned int codeB = codeKS(B, minX, minY, maxX, maxY);
- while (codeA | codeB)
- {
- // отрезки полностью невидимые
- if (codeA & codeB) return false;
- // чтобы не разбирать много случаев
- // для определенности за пределами области
- // видимости будем рассматривать только точку A
- if (codeA == 0)
- {
- swap(A, B);
- swap(codeA, codeB);
- }
- if (codeA & 1) // слева
- {
- A.y = A.y + (minX - A.x) * (B.y - A.y) / (B.x - A.x);
- A.x = minX;
- }
- else if (codeA & 2) // справа
- {
- A.y = A.y + (A.x - maxX) * (B.y - A.y) / (A.x - B.x);
- A.x = maxX;
- }
- else if (codeA & 4) // снизу
- {
- A.x = A.x + (B.x - A.x) * (A.y - minY) / (A.y - B.y);
- A.y = minY;
- }
- else // codeA & 8 == 1, сверху
- {
- A.x = A.x + (B.x - A.x) * (maxY - A.y) / (B.y - A.y);
- A.y = maxY;
- }
- // обновляем код
- codeA = codeKS(A, minX, minY, maxX, maxY);
- }
- return true;
- }
- // MyForm.h
- #pragma once
- namespace Moskvitin {
- using namespace System;
- using namespace System::ComponentModel;
- using namespace System::Collections;
- using namespace System::Windows::Forms;
- using namespace System::Data;
- using namespace System::Drawing;
- using namespace std;
- mat3 T = mat3(1.f); // матрица, в которой накапливаются все преобразования
- mat3 initT; // матрица начального преобразования
- vec2 Vc; // координаты левого нижнего угла
- vec2 V; // размеры прямоугольника в пространстве графика
- vec2 Vc_work, V_work; // рабочие параметры прямоугольника
- /// <summary>
- /// Сводка для MyForm
- /// </summary>
- public ref class MyForm : public System::Windows::Forms::Form
- {
- public:
- MyForm(void)
- {
- InitializeComponent();
- //
- //TODO: добавьте код конструктора
- //
- }
- protected:
- /// <summary>
- /// Освободить все используемые ресурсы.
- /// </summary>
- ~MyForm()
- {
- if (components)
- {
- delete components;
- }
- }
- private: System::Windows::Forms::OpenFileDialog^ openFileDialog;
- protected:
- private:
- /// <summary>
- /// Обязательная переменная конструктора.
- /// </summary>
- System::ComponentModel::Container^ components;
- #pragma region Windows Form Designer generated code
- /// <summary>
- /// Требуемый метод для поддержки конструктора — не изменяйте
- /// содержимое этого метода с помощью редактора кода.
- /// </summary>
- void InitializeComponent(void)
- {
- this->openFileDialog = (gcnew System::Windows::Forms::OpenFileDialog());
- this->SuspendLayout();
- //
- // openFileDialog
- //
- this->openFileDialog->DefaultExt = L"txt";
- this->openFileDialog->Filter = L" Текстовые файлы (*.txt)|*.txt|Все файлы (*.*)|*.*";
- this->openFileDialog->Title = L"Открыть файл";
- //
- // MyForm
- //
- this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
- this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
- this->ClientSize = System::Drawing::Size(284, 261);
- this->DoubleBuffered = true;
- this->KeyPreview = true;
- this->MinimumSize = System::Drawing::Size(155, 120);
- this->Name = L"MyForm";
- this->Text = L"MyForm";
- this->Load += gcnew System::EventHandler(this, &MyForm::MyForm_Load);
- this->Paint += gcnew System::Windows::Forms::PaintEventHandler(this, &MyForm::MyForm_Paint);
- this->KeyDown += gcnew System::Windows::Forms::KeyEventHandler(this, &MyForm::MyForm_KeyDown);
- this->Resize += gcnew System::EventHandler(this, &MyForm::MyForm_Resize);
- this->ResumeLayout(false);
- }
- #pragma endregion
- private: float left = 30, right = 100, top = 20, bottom = 50; // расстояния до границ окна
- float minX = left, maxX; // диапазон изменения координат x
- float minY = top, maxY; // диапазон изменения координат y
- float Wcx = left, Wcy; // координаты левого нижнего угла прямоугольника
- float Wx, Wy; // ширина и высота прямоугольника
- int numXsect = 5, numYsect = 5; // количество секций координатной сетки по осям
- // инициализация остальных параметров
- private: System::Void rectCalc() {
- maxX = ClientRectangle.Width - right; // диапазон изменения координат x
- maxY = ClientRectangle.Height - bottom; // диапазон изменения координат y
- Wcy = maxY; // координаты левого нижнего угла прямоугольника
- Wx = maxX - left; // ширина прямоугольника
- Wy = maxY - top;
- }
- private: System::Void worldRectCalc() {
- Vc_work = normalize(T * vec3(Vc, 1.f));
- V_work = mat2(T) * V;
- }
- // сама функция
- private: float f(float x) {
- return tan(x);
- }
- // проверка, определена ли функция в точке x
- private: bool f_exists(float x, float delta) {
- return fabs(2.f * acos(cos(x)) - Math::PI) > delta;
- }
- private: System::Void MyForm_Paint(System::Object^ sender, System::Windows::Forms::PaintEventArgs^ e) {
- // описываем переменную g - область рисования, ссылку на объект типа System::Drawing::Graphics^
- Graphics^ g = e->Graphics;
- Pen^ rectPen = gcnew Pen(Color::Black, 2); // черная ручка
- g->DrawRectangle(rectPen, left, top, Wx, Wy); // рисуем область видимости
- Pen^ pen = gcnew Pen(Color::Blue, 1); // ручка для рисовки графика функции
- float deltaX = V_work.x / Wx; // шаг по x в мировых координатах
- bool hasStart;
- vec2 start; // точка начала отрезка в координатах экрана
- float x, y; // переменные для координат точки в мировой СК
- start.x = Wcx; // для начальной точки первого отрезка устанавливаем координату x
- x = Vc_work.x; // координата x начальной точки первого отрезка в мировых координатах
- hasStart = f_exists(x, deltaX);
- if (hasStart)
- {
- y = f(x); // координата y начальной точки в мировых координатах
- start.y = Wcy - (y - Vc_work.y) / V_work.y * Wy; // вычисляем соответствующее значение в координатах экрана
- }
- while (start.x < maxX)
- {
- float deltaY; // высота точки в прямоугольнике (доля общей высоты)
- float red, green, blue; // компоненты цвета отрезка
- vec2 end;// точка конца отрезка в координатах экрана
- bool hasEnd;
- end.x = start.x + 1.f; // координата x отличается на единицу
- x += deltaX; // координата x конечной точки отрезка в мировых координатах
- hasEnd = f_exists(x, deltaX);
- if (hasEnd)
- {
- y = f(x); // координата y начальной точки в мировых координатах
- // вычисляем соответствующее значение в координатах экрана
- deltaY = (y - Vc_work.y) / V_work.y;
- end.y = Wcy - deltaY * Wy;
- }
- vec2 tmpEnd = end;
- bool visible = hasStart && hasEnd && clip(start, end, minX, minY, maxX, maxY);
- if (visible) { // если отрезок видим
- if (deltaY > 1.f) deltaY = 1.f; // нормализуем значение высоты точки
- if (deltaY < 0.f) deltaY = 0.f; // на случай, если отрезок отсекался
- green = 510.f * deltaY; // предварительное вычисление произведения
- if (deltaY < 0.5) { // если точка ниже середины области видимости
- // компонента зеленого уже вычислена
- blue = 255.f - green; // синий дополняет зеленый
- red = 0.f; // красный равен нулю
- }
- else { // если точка не ниже середины
- blue = 0.f; // синий равен нулю
- red = green - 255.f; // вычисляем красный и зеленый
- green = 510.f - green; // с использованием вычисленного произведения
- }
- pen->Color = Color::FromArgb(red, green, blue); // меняем цвет пера
- // после отсечения, start и end - концы видимой части отрезка
- g->DrawLine(pen, start.x, start.y, end.x, end.y); // отрисовка видимых частей
- }
- // конечная точка неотсеченного отрезка становится начальной точкой следующего
- start = tmpEnd;
- hasStart = hasEnd;
- }
- Pen^ gridPen = gcnew Pen(Color::Black, 1);
- SolidBrush^ drawBrush = gcnew SolidBrush(Color::Black);
- System::Drawing::Font^ drawFont = gcnew System::Drawing::Font("Arial", 8);
- // координатная сетка по X
- float gridStep_x = Wx / numXsect; // расстояние между линиями сетки по x
- float grid_dX = V_work.x / numXsect; // расстояние между линиями сетки по x в мировых координатах
- float tick_x = Vc_work.x; // значение соответствующее первой линии сетки
- for (int i = 0; i <= numXsect; i++) { // цикл по количеству линий
- float tmpXCoord = Wcx + i * gridStep_x;
- g->DrawLine(gridPen, tmpXCoord, Wcy, tmpXCoord, Wcy - Wy); // i-я вертикальная линия
- if (i > 0 && i < numXsect) // если линия не крайняя
- g->DrawString(tick_x.ToString("F4"), drawFont, drawBrush, tmpXCoord, Wcy);
- tick_x += grid_dX; // вычисляем значение, соответствующее следующей линии
- }
- // координатная сетка по Y
- float gridStep_y = Wy / numYsect; // расстояние между линиями сетки по y
- float grid_dY = V_work.y / numYsect; // расстояние между линиями сетки по y в мировых координатах
- float tick_y = Vc_work.y; // значение соответствующее первой линии сетки
- for (int i = 0; i <= numYsect; i++) { // цикл по количеству линий
- float tmpYCoord = Wcy - i * gridStep_y;
- g->DrawLine(gridPen, Wcx, tmpYCoord, Wcx + Wx, tmpYCoord); // i-я горизонтальная линия
- if (i > 0 && i < numYsect) // если линия не крайняя
- g->DrawString(tick_y.ToString("F4"), drawFont, drawBrush, Wcx + Wx, tmpYCoord);
- tick_y += grid_dY; // вычисляем значение, соответствующее следующей линии
- }
- }
- private: System::Void MyForm_Resize(System::Object^ sender, System::EventArgs^ e) {
- // Добавляем устойчивость рисунка относительно изменения размера окна
- Refresh();
- // передподсчет сторон прямоугольника
- rectCalc();
- }
- private: System::Void MyForm_Load(System::Object^ sender, System::EventArgs^ e) {
- initT = mat3(1.f);
- T = initT;
- // изначально центр прямоугольника находится в начале координат
- Vc = vec2(-2.f, -2.f);
- V = vec2(4.f, 4.f);
- rectCalc();
- worldRectCalc();
- }
- private: System::Void MyForm_KeyDown(System::Object^ sender, System::Windows::Forms::KeyEventArgs^ e) {
- float centerX = Vc_work.x + V_work.x / 2; // координаты центра прямоугольника
- float centerY = Vc_work.y + V_work.y / 2; // в мировой системе координат
- switch (e->KeyCode)
- {
- // сброс всех преобразований
- case Keys::Escape:
- T = initT;
- break;
- // сдвиг графика ВПРАВО на один пиксел
- case Keys::A:
- T = translate(-V_work.x / Wx, 0.f) * T;
- break;
- // сдвиг графика ВЛЕВО на один пиксел
- case Keys::D:
- T = translate(V_work.x / Wx, 0.f) * T;
- break;
- // сдвиг графика ВНИЗ на один пиксел
- case Keys::W:
- T = translate(0.f, V_work.y / Wy) * T;
- break;
- // сдвиг графика ВВЕРХ на один пиксел
- case Keys::S:
- T = translate(0.f, -V_work.y / Wy) * T;
- break;
- // увеличение числа секций координатной сетки по оси Ox
- case Keys::D1:
- ++numXsect;
- break;
- // уменьшение числа секций координатной сетки по оси Ox
- case Keys::D2:
- numXsect = max(numXsect - 1, 2);
- break;
- // увеличение числа секций координатной сетки по оси Oy
- case Keys::D3:
- ++numYsect;
- break;
- // уменьшение числа секций координатной сетки по оси Oy
- case Keys::D4:
- numYsect = max(numYsect - 1, 2);
- break;
- // равномерное увеличение прямоугольника в мировой СК относительно центра в 1.1 раз
- case Keys::Z:
- T = translate(-centerX, -centerY) * T; // перенос начала координат в центр
- T = scale(1.1) * T; // масштабирование относительно начала координат
- T = translate(centerX, centerY) * T; // возврат позиции начала координат
- break;
- // равномерное уменьшение прямоугольника в мировой СК относительно центра в 1.1 раз
- case Keys::X:
- T = translate(-centerX, -centerY) * T; // перенос начала координат в центр
- T = scale(10.f / 11.f) * T; // масштабирование относительно начала координат
- T = translate(centerX, centerY) * T; // возврат позиции начала координат
- break;
- // увеличение прямоугольника в мировой СК относительно центра по Ox в 1.1 раз
- case Keys::T:
- T = translate(-centerX, -centerY) * T; // перенос начала координат в центр
- T = scale(1.1, 1) * T; // масштабирование относительно начала координат
- T = translate(centerX, centerY) * T; // возврат позиции начала координат
- break;
- // уменьшение прямоугольника в мировой СК относительно центра по Ox в 1.1 раз
- case Keys::G:
- T = translate(-centerX, -centerY) * T; // перенос начала координат в центр
- T = scale(10.f / 11.f, 1) * T; // масштабирование относительно начала координат
- T = translate(centerX, centerY) * T; // возврат позиции начала координат
- break;
- // увеличение прямоугольника в мировой СК относительно центра по Oy в 1.1 раз
- case Keys::Y:
- T = translate(-centerX, -centerY) * T; // перенос начала координат в центр
- T = scale(1, 1.1) * T; // масштабирование относительно начала координат
- T = translate(centerX, centerY) * T; // возврат позиции начала координат
- break;
- // уменьшение прямоугольника в мировой СК относительно центра по Oy в 1.1 раз
- case Keys::H:
- T = translate(-centerX, -centerY) * T; // перенос начала координат в центр
- T = scale(1, 10.f / 11.f) * T; // масштабирование относительно начала координат
- T = translate(centerX, centerY) * T; // возврат позиции начала координат
- break;
- default:
- break;
- }
- worldRectCalc();
- Refresh();
- }
- };
- }
- // MyForm.cpp
- #include <vector>
- #include "Matrix.h"
- #include "Transform.h"
- #include "Clip.h"
- #include "MyForm.h"
- using namespace System;
- using namespace System::Windows::Forms;
- [STAThreadAttribute]
- void Main(cli::array<String^>^ args) {
- Application::EnableVisualStyles();
- Application::SetCompatibleTextRenderingDefault(false);
- Moskvitin::MyForm form;
- Application::Run(% form);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement