diff options
Diffstat (limited to 'task05_2D/Guschin/MyForm.h')
| -rw-r--r-- | task05_2D/Guschin/MyForm.h | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/task05_2D/Guschin/MyForm.h b/task05_2D/Guschin/MyForm.h new file mode 100644 index 0000000..7e76f41 --- /dev/null +++ b/task05_2D/Guschin/MyForm.h @@ -0,0 +1,189 @@ +#pragma once + +namespace Guschin { + + 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; + + vec2 Vc; + vec2 V; + vec2 Vc_work, V_work; + mat3 T; + mat3 initT; + + public ref class MyForm : public System::Windows::Forms::Form + { + public: + MyForm(void) + { + InitializeComponent(); + } + + protected: + ~MyForm() + { + if (components) + { + delete components; + } + } + + private: + System::ComponentModel::Container ^components; + +#pragma region Windows Form Designer generated code + void InitializeComponent(void) + { + this->SuspendLayout(); + // + // MyForm + // + this->AutoScaleDimensions = System::Drawing::SizeF(8, 16); + this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font; + this->ClientSize = System::Drawing::Size(737, 686); + this->KeyPreview = true; + this->Margin = System::Windows::Forms::Padding(4, 4, 4, 4); + 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; + float minY = top, maxY; + float Wcx = left, Wcy; + float Wx, Wy; + + private: + System::Void rectCalc() { + maxX = ClientRectangle.Width - right; + maxY = ClientRectangle.Height - bottom; + Wcy = maxY; + Wx = maxX - left; + Wy = maxY - top; + } + System::Void worldRectCalc() + { + Vc_work = normalize(T * vec3(Vc, 1.f)); + V_work = mat2(T) * V; + } + float f(float x) + { + return tan(x); + } + bool f_exists(float x, float delta) + { + return fabs(2.f * acos(cos(x)) - Math::PI) > delta; + } + private: + System::Void MyForm_Resize(System::Object^ sender, System::EventArgs^ e) { + rectCalc(); + Refresh(); + } + private: + System::Void MyForm_Paint(System::Object^ sender, System::Windows::Forms::PaintEventArgs^ e) { + Graphics^ g = e->Graphics; + g->Clear(Color::Aquamarine); + + 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; + bool hasStart, hasEnd; + vec2 start, end; + float x, y; + + start.x = Wcx; + x = Vc_work.x; + hasStart = f_exists(x, deltaX); + if (hasStart) + { + y = f(x); + start.y = Wcy - (y - Vc_work.y) / V_work.y * Wy; + } + + float deltaY; + float red, green, blue; + while (start.x < maxX) + { + end.x = start.x + 1.f; + x += deltaX; + hasEnd = f_exists(x, deltaX); + if (hasEnd) + { + y = f(x); + 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); + g->DrawLine(pen, start.x, start.y, end.x, end.y); + } + start = tmpEnd; + hasStart = hasEnd; + } + } + 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::Z: + T = translate(-centerX, -centerY) * T; + T = scale(1.1) * T; + T = translate(centerX, centerY) * T; + break; + default: + break; + } + worldRectCalc(); + Refresh(); + } + }; +} |