summaryrefslogtreecommitdiff
path: root/task05_2D/Guschin/MyForm.h
diff options
context:
space:
mode:
Diffstat (limited to 'task05_2D/Guschin/MyForm.h')
-rw-r--r--task05_2D/Guschin/MyForm.h189
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();
+ }
+ };
+}