"#pragma once #define WIN32_LEAN_AND_MEAN #include...

बनाया गया: 25 नवंबर 2025

का उपयोग करके उत्तर दिया गया GPT-5.1 Thinking द्वारा Chat01

प्रश्न

"#pragma once
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

using namespace System;
using namespace System::Drawing;
using namespace System::Windows::Forms;
using namespace System::Collections::Generic;
using namespace System::Drawing::Drawing2D;
using namespace System::Diagnostics;
using namespace System::Globalization;

typedef void(__cdecl* P_MANIP)(int, bool, float, float, float, int, int, float, bool, float, unsigned int, float**, size_t*, float*, float*, float*, size_t*, float*);
typedef void(__cdecl* P_FREE)(float*);
typedef void(__cdecl* P_START)(int, bool, float, float, float, int, int, float, bool, float, unsigned int);

namespace TESTAGP {

text
public enum class OptimizerBackend { AgpCpp = 0, Optuna = 1, IOpt = 2 }; public ref class MyForm : public Form { public: MyForm(HMODULE hLib) : hLib(hLib) { this->SetStyle(ControlStyles::AllPaintingInWmPaint | ControlStyles::UserPaint | ControlStyles::OptimizedDoubleBuffer, true); this->Text = L"AGP Manipulator 2D"; this->ClientSize = System::Drawing::Size(1200, 800); this->Resize += gcnew EventHandler(this, &MyForm::OnResize); fManip = reinterpret_cast<P_MANIP>(GetProcAddress(hLib, "AGP_Manip2D")); pFree = reinterpret_cast<P_FREE>(GetProcAddress(hLib, "AGP_Free")); pStart = reinterpret_cast<P_START>(GetProcAddress(hLib, "AgpStartManipND")); angles = gcnew List<float>(0); lengths = gcnew List<float>(0); backend = OptimizerBackend::AgpCpp; InitUI(); ResetRandomConfig(); } private: initonly HMODULE hLib; initonly P_MANIP fManip; initonly P_FREE pFree; initonly P_START pStart; OptimizerBackend backend; ComboBox^ cbBackend; int nSegments; bool variableLengths; List<float>^ angles; List<float>^ lengths; CheckBox^ cbVarLen; NumericUpDown^ nudMinTheta; NumericUpDown^ nudBaseLength; NumericUpDown^ nudStretchFactor; NumericUpDown^ nudTargetX; NumericUpDown^ nudTargetY; NumericUpDown^ nudLevels; NumericUpDown^ nudMaxIter; CheckBox^ cbAdaptive; NumericUpDown^ nudR; NumericUpDown^ nudEps; Button^ btnAdd; Button^ btnRem; Button^ btnOptimize; Label^ lblInfo; System::UInt32 rngState = 0xA5C39E0Du; void InitUI() { cbBackend = gcnew ComboBox(); cbBackend->Location = Point(920, 52); cbBackend->Width = 260; // Увеличил ширину для лучшего отображения cbBackend->Height = 28; // Добавил высоту для согласованности cbBackend->DropDownStyle = ComboBoxStyle::DropDownList; cbBackend->Font = gcnew System::Drawing::Font("Yu Gothic UI", 11, FontStyle::Bold); // Размер 11 как у других элементов // Установим тот же цвет фона, что у других элементов cbBackend->BackColor = System::Drawing::SystemColors::Info; // Сделаем границу более заметной для согласованности cbBackend->FlatStyle = FlatStyle::Flat; cbBackend->Items->Add(L"AGP"); cbBackend->Items->Add(L"Optuna"); cbBackend->Items->Add(L"iOpt"); cbBackend->SelectedIndex = 0; cbBackend->SelectedIndexChanged += gcnew EventHandler(this, &MyForm::OnBackendChanged); this->Controls->Add(cbBackend); Label^ L; L = gcnew Label(); L->Text = L"Мин. угол (рад)"; L->Location = Point(20, 20); L->Width = 200; L->Font = gcnew System::Drawing::Font("Yu Gothic UI", 11, FontStyle::Bold); this->Controls->Add(L); nudMinTheta = gcnew NumericUpDown(); nudMinTheta->Location = Point(20, 52); nudMinTheta->Width = 200; nudMinTheta->DecimalPlaces = 3; nudMinTheta->Minimum = Decimal(1) / Decimal(100); nudMinTheta->Maximum = Decimal(314159) / Decimal(100000); nudMinTheta->Value = Decimal(150) / Decimal(100); nudMinTheta->Font = gcnew System::Drawing::Font("Yu Gothic UI", 10, FontStyle::Bold); nudMinTheta->ValueChanged += gcnew EventHandler(this, &MyForm::OnAnyChanged); this->Controls->Add(nudMinTheta); L = gcnew Label(); L->Text = L"Базовая длина"; L->Location = Point(245, 20); L->Width = 200; L->Font = gcnew System::Drawing::Font("Yu Gothic UI", 11, FontStyle::Bold); this->Controls->Add(L); nudBaseLength = gcnew NumericUpDown(); nudBaseLength->Location = Point(245, 52); nudBaseLength->Width = 200; nudBaseLength->DecimalPlaces = 2; nudBaseLength->Minimum = Decimal(1) / Decimal(2); nudBaseLength->Maximum = Decimal(200) / Decimal(100); nudBaseLength->Value = Decimal(100) / Decimal(100); nudBaseLength->Font = gcnew System::Drawing::Font("Yu Gothic UI", 10, FontStyle::Bold); nudBaseLength->ValueChanged += gcnew EventHandler(this, &MyForm::OnAnyChanged); this->Controls->Add(nudBaseLength); L = gcnew Label(); L->Text = L"Коэф. растяжения"; L->Location = Point(470, 20); L->Width = 200; L->Font = gcnew System::Drawing::Font("Yu Gothic UI", 11, FontStyle::Bold); this->Controls->Add(L); nudStretchFactor = gcnew NumericUpDown(); nudStretchFactor->Location = Point(470, 52); nudStretchFactor->Width = 200; nudStretchFactor->DecimalPlaces = 2; nudStretchFactor->Minimum = Decimal(100) / Decimal(100); nudStretchFactor->Maximum = Decimal(150) / Decimal(100); nudStretchFactor->Increment = Decimal(1) / Decimal(100); nudStretchFactor->Value = Decimal(150) / Decimal(100); nudStretchFactor->Font = gcnew System::Drawing::Font("Yu Gothic UI", 10, FontStyle::Bold); nudStretchFactor->ValueChanged += gcnew EventHandler(this, &MyForm::OnAnyChanged); this->Controls->Add(nudStretchFactor); cbVarLen = gcnew CheckBox(); cbVarLen->Text = L"Переменные длины"; cbVarLen->Location = Point(695, 52); cbVarLen->Width = 200; cbVarLen->Checked = false; cbVarLen->Font = gcnew System::Drawing::Font("Yu Gothic UI", 11, FontStyle::Bold); cbVarLen->CheckedChanged += gcnew EventHandler(this, &MyForm::OnAnyChanged); this->Controls->Add(cbVarLen); L = gcnew Label(); L->Text = L"Цель X"; L->Location = Point(20, 107); L->Width = 200; L->Font = gcnew System::Drawing::Font("Yu Gothic UI", 11, FontStyle::Bold); this->Controls->Add(L); nudTargetX = gcnew NumericUpDown(); nudTargetX->Location = Point(20, 139); nudTargetX->Width = 200; nudTargetX->DecimalPlaces = 2; nudTargetX->Minimum = Decimal(-100) / Decimal(10); nudTargetX->Maximum = Decimal(100) / Decimal(10); nudTargetX->Value = Decimal(25) / Decimal(10); nudTargetX->Font = gcnew System::Drawing::Font("Yu Gothic UI", 10, FontStyle::Bold); nudTargetX->ValueChanged += gcnew EventHandler(this, &MyForm::OnAnyChanged); this->Controls->Add(nudTargetX); L = gcnew Label(); L->Text = L"Цель Y"; L->Location = Point(245, 107); L->Width = 200; L->Font = gcnew System::Drawing::Font("Yu Gothic UI", 11, FontStyle::Bold); this->Controls->Add(L); nudTargetY = gcnew NumericUpDown(); nudTargetY->Location = Point(245, 139); nudTargetY->Width = 200; nudTargetY->DecimalPlaces = 2; nudTargetY->Minimum = Decimal(-100) / Decimal(10); nudTargetY->Maximum = Decimal(100) / Decimal(10); nudTargetY->Value = Decimal(-10) / Decimal(10); nudTargetY->Font = gcnew System::Drawing::Font("Yu Gothic UI", 10, FontStyle::Bold); nudTargetY->ValueChanged += gcnew EventHandler(this, &MyForm::OnAnyChanged); this->Controls->Add(nudTargetY); L = gcnew Label(); L->Text = L"Глубина развёрток"; L->Location = Point(470, 107); L->Width = 200; L->Font = gcnew System::Drawing::Font("Yu Gothic UI", 11, FontStyle::Bold); this->Controls->Add(L); nudLevels = gcnew NumericUpDown(); nudLevels->Location = Point(470, 139); nudLevels->Width = 200; nudLevels->Minimum = 7; nudLevels->Maximum = 20; nudLevels->Value = 12; nudLevels->Font = gcnew System::Drawing::Font("Yu Gothic UI", 10, FontStyle::Bold); nudLevels->ValueChanged += gcnew EventHandler(this, &MyForm::OnAnyChanged); this->Controls->Add(nudLevels); L = gcnew Label(); L->Text = L"Надежность (r)"; L->Location = Point(695, 107); L->Width = 200; L->Font = gcnew System::Drawing::Font("Yu Gothic UI", 11, FontStyle::Bold); this->Controls->Add(L); nudR = gcnew NumericUpDown(); nudR->Location = Point(695, 139); nudR->Width = 200; nudR->DecimalPlaces = 2; nudR->Minimum = Decimal(100) / Decimal(100); nudR->Maximum = Decimal(2000) / Decimal(100); nudR->Value = Decimal(250) / Decimal(100); nudR->Font = gcnew System::Drawing::Font("Yu Gothic UI", 10, FontStyle::Bold); nudR->ValueChanged += gcnew EventHandler(this, &MyForm::OnAnyChanged); this->Controls->Add(nudR); cbAdaptive = gcnew CheckBox(); cbAdaptive->Text = L"Адаптивная схема"; cbAdaptive->Location = Point(920, 139); cbAdaptive->Width = 200; cbAdaptive->Checked = true; cbAdaptive->Font = gcnew System::Drawing::Font("Yu Gothic UI", 11, FontStyle::Bold); cbAdaptive->CheckedChanged += gcnew EventHandler(this, &MyForm::OnAnyChanged); this->Controls->Add(cbAdaptive); L = gcnew Label(); L->Text = L"Точность"; L->Location = Point(20, 194); L->Width = 200; L->Font = gcnew System::Drawing::Font("Yu Gothic UI", 11, FontStyle::Bold); this->Controls->Add(L); nudEps = gcnew NumericUpDown(); nudEps->Location = Point(20, 226); nudEps->Width = 200; nudEps->DecimalPlaces = 9; nudEps->Minimum = Decimal(1) / Decimal(1000000000); nudEps->Maximum = Decimal(1) / Decimal(10); nudEps->Value = Decimal(1) / Decimal(100000); nudEps->Font = gcnew System::Drawing::Font("Yu Gothic UI", 10, FontStyle::Bold); nudEps->ValueChanged += gcnew EventHandler(this, &MyForm::OnAnyChanged); this->Controls->Add(nudEps); L = gcnew Label(); L->Text = L"Макс. итераций"; L->Location = Point(245, 194); L->Width = 200; L->Font = gcnew System::Drawing::Font("Yu Gothic UI", 11, FontStyle::Bold); this->Controls->Add(L); nudMaxIter = gcnew NumericUpDown(); nudMaxIter->Location = Point(245, 226); nudMaxIter->Width = 200; nudMaxIter->Minimum = 10; nudMaxIter->Maximum = 500000; nudMaxIter->Value = 1000; nudMaxIter->Font = gcnew System::Drawing::Font("Yu Gothic UI", 10, FontStyle::Bold); nudMaxIter->Increment = 100; nudMaxIter->ValueChanged += gcnew EventHandler(this, &MyForm::OnAnyChanged); this->Controls->Add(nudMaxIter); btnAdd = gcnew Button(); btnAdd->Text = L"+ Звено"; btnAdd->Location = Point(465, 226); btnAdd->Width = 90; btnAdd->Height = 35; btnAdd->BackColor = System::Drawing::SystemColors::Info; btnAdd->Cursor = Cursors::Hand; btnAdd->FlatAppearance->BorderColor = Color::FromArgb(64, 64, 64); btnAdd->FlatAppearance->BorderSize = 3; btnAdd->FlatAppearance->MouseDownBackColor = Color::FromArgb(128, 128, 255); btnAdd->FlatAppearance->MouseOverBackColor = Color::FromArgb(192, 192, 255); btnAdd->FlatStyle = FlatStyle::Flat; btnAdd->Font = gcnew System::Drawing::Font("Yu Gothic UI", 11, FontStyle::Bold); btnAdd->ForeColor = System::Drawing::SystemColors::ControlDarkDark; btnAdd->Click += gcnew EventHandler(this, &MyForm::OnAddClick); this->Controls->Add(btnAdd); btnRem = gcnew Button(); btnRem->Text = L"- Звено"; btnRem->Location = Point(560, 226); btnRem->Width = 90; btnRem->Height = 35; btnRem->BackColor = System::Drawing::SystemColors::Info; btnRem->Cursor = Cursors::Hand; btnRem->FlatAppearance->BorderColor = Color::FromArgb(64, 64, 64); btnRem->FlatAppearance->BorderSize = 3; btnRem->FlatAppearance->MouseDownBackColor = Color::FromArgb(128, 128, 255); btnRem->FlatAppearance->MouseOverBackColor = Color::FromArgb(192, 192, 255); btnRem->FlatStyle = FlatStyle::Flat; btnRem->Font = gcnew System::Drawing::Font("Yu Gothic UI", 11, FontStyle::Bold); btnRem->ForeColor = System::Drawing::SystemColors::ControlDarkDark; btnRem->Click += gcnew EventHandler(this, &MyForm::OnRemClick); this->Controls->Add(btnRem); btnOptimize = gcnew Button(); btnOptimize->Text = L"Оптимизировать"; btnOptimize->Location = Point(680, 226); btnOptimize->Width = 150; btnOptimize->Height = 35; btnOptimize->BackColor = System::Drawing::SystemColors::Info; btnOptimize->Cursor = Cursors::Hand; btnOptimize->FlatAppearance->BorderColor = Color::FromArgb(64, 64, 64); btnOptimize->FlatAppearance->BorderSize = 3; btnOptimize->FlatAppearance->MouseDownBackColor = Color::FromArgb(128, 128, 255); btnOptimize->FlatAppearance->MouseOverBackColor = Color::FromArgb(192, 192, 255); btnOptimize->FlatStyle = FlatStyle::Flat; btnOptimize->Font = gcnew System::Drawing::Font("Yu Gothic UI", 11, FontStyle::Bold); btnOptimize->ForeColor = System::Drawing::SystemColors::ControlDarkDark; btnOptimize->Click += gcnew EventHandler(this, &MyForm::OnOptimizeClick); this->Controls->Add(btnOptimize); lblInfo = gcnew Label(); lblInfo->Location = Point(835, 194); lblInfo->Size = System::Drawing::Size(335, 140); lblInfo->BorderStyle = BorderStyle::FixedSingle; lblInfo->Text = L"Готов"; lblInfo->Font = gcnew System::Drawing::Font("Yu Gothic UI", 10, FontStyle::Bold); this->Controls->Add(lblInfo); } void ResetRandomConfig() { nSegments = 1; angles->Clear(); lengths->Clear(); angles->Add(1.57079637f); lengths->Add(static_cast<float>(nudBaseLength->Value)); variableLengths = false; this->Invalidate(); } float Rand01() { rngState ^= rngState << 13; rngState ^= rngState >> 17; rngState ^= rngState << 5; return static_cast<float>(static_cast<double>(static_cast<unsigned int>(rngState)) / 4294967296.0); } float RandAngle() { return (Rand01() * 6.28318548f) - 3.14159274f; } void RunAgpCpp() { variableLengths = cbVarLen->Checked; float minTheta = static_cast<float>(nudMinTheta->Value); float tx = static_cast<float>(nudTargetX->Value); float ty = static_cast<float>(nudTargetY->Value); int levels = static_cast<int>(nudLevels->Value); int maxIter = static_cast<int>(nudMaxIter->Value); bool adaptive = cbAdaptive->Checked; float r_param = static_cast<float>(nudR->Value); float eps = static_cast<float>(nudEps->Value); unsigned int seed = static_cast<unsigned int>(GetTickCount()); pStart(nSegments, variableLengths, minTheta, tx, ty, levels, maxIter, r_param, adaptive, eps, seed); LARGE_INTEGER t0, t1, fq; QueryPerformanceCounter(&t0); float* bestQ = nullptr; size_t bestQLen = 0; float bestX = 0.0f; float bestY = 0.0f; float bestF = 0.0f; size_t actualIterations = 0u; float achievedEps = 0.0f; fManip(nSegments, variableLengths, minTheta, tx, ty, levels, maxIter, r_param, adaptive, eps, seed, &bestQ, &bestQLen, &bestX, &bestY, &bestF, &actualIterations, &achievedEps); QueryPerformanceCounter(&t1); QueryPerformanceFrequency(&fq); double micros = 1e6 * static_cast<double>(t1.QuadPart - t0.QuadPart) / static_cast<double>(fq.QuadPart); angles->Clear(); for (int i = 0; i < nSegments; ++i) { angles->Add(bestQ[i]); } if (variableLengths) { lengths->Clear(); for (int i = 0; i < nSegments; ++i) { lengths->Add(bestQ[nSegments + i]); } } else { lengths->Clear(); for (int i = 0; i < nSegments; ++i) { lengths->Add(static_cast<float>(nudBaseLength->Value)); } } pFree(bestQ); float dx = bestX - tx; float dy = bestY - ty; lblInfo->Text = String::Format( L"Результат:\n" L"Близость захвата: {0:F5}\n" L"Функционал: {1:F5}\n" L"Точка: ({2:F3}, {3:F3})\n" L"Время: {4:F0} мкс\n" L"Число шагов: {5}\n" L"Достигнутая точность: {6:E3}", System::Math::Sqrt(dx * dx + dy * dy), bestF, bestX, bestY, micros, actualIterations, achievedEps); this->Invalidate(); } bool ParseFloat(String^ s, float% out) { return Single::TryParse( s, NumberStyles::Float, CultureInfo::InvariantCulture, out); } void RunPythonBackend(String^ which) { int nSeg = nSegments; bool varLen = cbVarLen->Checked; float minTheta = static_cast<float>(nudMinTheta->Value); float tx = static_cast<float>(nudTargetX->Value); float ty = static_cast<float>(nudTargetY->Value); int levels = static_cast<int>(nudLevels->Value); int maxIter = static_cast<int>(nudMaxIter->Value); float r_param = static_cast<float>(nudR->Value); float eps = static_cast<float>(nudEps->Value); bool adaptive = cbAdaptive->Checked; // Добавляем состояние чекбокса String^ pythonExe = System::IO::Path::Combine( Application::StartupPath, "env", "Scripts", "python.exe"); String^ scriptPath = System::IO::Path::Combine( Application::StartupPath, "optimizer_bridge.py"); ProcessStartInfo^ psi = gcnew ProcessStartInfo(); psi->FileName = pythonExe; // Добавляем adaptive как 11-й параметр psi->Arguments = String::Format( CultureInfo::InvariantCulture, "\"{0}\" {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11}", scriptPath, which, nSeg, varLen ? 1 : 0, minTheta, tx, ty, levels, maxIter, r_param, eps, adaptive ? 1 : 0 // Передаем 1 или 0 ); // Остальной код без изменений... psi->UseShellExecute = false; psi->CreateNoWindow = true; psi->RedirectStandardOutput = true; psi->RedirectStandardError = false; psi->WorkingDirectory = Application::StartupPath; Process^ proc = Process::Start(psi); String^ stdoutAll = proc->StandardOutput->ReadToEnd(); proc->WaitForExit(); float bestF = 0.0f; float bestX = 0.0f; float bestY = 0.0f; float achievedEps = 0.0f; int iterations = 0; float micros = 0.0f; array<float>^ tempAngles = gcnew array<float>(nSeg); array<float>^ tempLengths = gcnew array<float>(nSeg); for (int i = 0; i < nSeg; ++i) { tempAngles[i] = 0.0f; tempLengths[i] = static_cast<float>(nudBaseLength->Value); } array<String^>^ lines = stdoutAll->Split( gcnew array<wchar_t>{ '\r', '\n' }, StringSplitOptions::RemoveEmptyEntries); int qIndex = 0; for each (String ^ line in lines) { array<String^>^ parts = line->Split( gcnew array<wchar_t>{ ' ', '\t' }, StringSplitOptions::RemoveEmptyEntries); String^ key = parts[0]; if (key == "Q") { for (int i = 1; i < parts->Length && qIndex < (varLen ? 2 * nSeg : nSeg); ++i) { float qVal; if (ParseFloat(parts[i], qVal)) { if (qIndex < nSeg) { tempAngles[qIndex] = qVal; } else if (varLen && qIndex < 2 * nSeg) { tempLengths[qIndex - nSeg] = qVal; } ++qIndex; } } } else { String^ value = parts[1]; if (key == "BEST_F") { ParseFloat(value, bestF); } else if (key == "BEST_X") { ParseFloat(value, bestX); } else if (key == "BEST_Y") { ParseFloat(value, bestY); } else if (key == "ITERATIONS") { Int32::TryParse(value, iterations); } else if (key == "EPS") { ParseFloat(value, achievedEps); } else if (key == "TIME") { ParseFloat(value, micros); } } } angles->Clear(); lengths->Clear(); for (int i = 0; i < nSeg; ++i) { angles->Add(tempAngles[i]); lengths->Add(tempLengths[i]); } String^ anglesStr = ""; for each (float angle in angles) { anglesStr += angle.ToString("F3") + ", "; } anglesStr = anglesStr->TrimEnd(',', ' '); String^ lengthsStr = ""; for each (float length in lengths) { lengthsStr += length.ToString("F3") + ", "; } lengthsStr = lengthsStr->TrimEnd(',', ' '); float dx = bestX - tx; float dy = bestY - ty; double distance = Math::Sqrt(dx * dx + dy * dy); String^ resultText = String::Format( L"Результат:\n" L"Близость захвата: {0:F5}\n" L"Функционал: {1:F5}\n" L"Точка: ({2:F3}, {3:F3})\n" L"Время: {4:F0} мкс\n" L"Число шагов: {5}\n" L"Достигнутая точность: {6:E3}", distance, bestF, bestX, bestY, micros, iterations, achievedEps); lblInfo->Text = resultText; this->Invalidate(); this->Refresh(); } System::Void OnBackendChanged(System::Object^ sender, System::EventArgs^ e) { switch (cbBackend->SelectedIndex) { case 0: backend = OptimizerBackend::AgpCpp; cbAdaptive->Enabled = true; break; case 1: backend = OptimizerBackend::Optuna; cbAdaptive->Enabled = false; break; case 2: backend = OptimizerBackend::IOpt; cbAdaptive->Enabled = true; break; default: backend = OptimizerBackend::AgpCpp; cbAdaptive->Enabled = true; break; } } System::Void OnResize(System::Object^ sender, System::EventArgs^ e) { this->Invalidate(); } System::Void OnAnyChanged(System::Object^ sender, System::EventArgs^ e) { this->Invalidate(); } System::Void OnAddClick(System::Object^ sender, System::EventArgs^ e) { ++nSegments; angles->Add(RandAngle()); lengths->Add(static_cast<float>(nudBaseLength->Value)); this->Invalidate(); } System::Void OnRemClick(System::Object^ sender, System::EventArgs^ e) { if (nSegments > 1) { --nSegments; angles->RemoveAt(angles->Count - 1); lengths->RemoveAt(lengths->Count - 1); this->Invalidate(); } } System::Void OnOptimizeClick(System::Object^ sender, System::EventArgs^ e) { switch (backend) { case OptimizerBackend::AgpCpp: RunAgpCpp(); break; case OptimizerBackend::Optuna: RunPythonBackend(L"optuna"); break; case OptimizerBackend::IOpt: RunPythonBackend(L"iopt"); break; } } protected: virtual void OnPaint(PaintEventArgs^ e) override { Form::OnPaint(e); Graphics^ g = e->Graphics; g->SmoothingMode = System::Drawing::Drawing2D::SmoothingMode::HighQuality; g->Clear(this->BackColor); System::Drawing::Rectangle drawArea = System::Drawing::Rectangle(0, 180, this->ClientSize.Width, 620); g->FillRectangle(Brushes::White, drawArea); int leftWallX = drawArea.Left + this->ClientSize.Width * 25 / 100; Pen^ wallPen = gcnew Pen(Color::Black, 2); g->DrawLine(wallPen, leftWallX, drawArea.Top, leftWallX, drawArea.Bottom); HatchBrush^ hatchBrush = gcnew HatchBrush(HatchStyle::BackwardDiagonal, Color::LightGray, Color::White); g->FillRectangle(hatchBrush, leftWallX - 100, drawArea.Top, 100, drawArea.Height); float targetX = static_cast<float>(nudTargetX->Value); float targetY = static_cast<float>(nudTargetY->Value); int baseX = leftWallX; int baseY = drawArea.Top + 310; float pixelTargetX = static_cast<float>(baseX) + targetX * 160.0f; float pixelTargetY = static_cast<float>(baseY) - targetY * 160.0f; int rightWallX = static_cast<int>(pixelTargetX + 8.0f); rightWallX = Math::Min(rightWallX, drawArea.Right - 10); Pen^ dashedPen = gcnew Pen(Color::Black, 2); dashedPen->DashStyle = DashStyle::Dash; g->DrawLine(dashedPen, rightWallX, drawArea.Top, rightWallX, drawArea.Bottom); g->FillRectangle(hatchBrush, rightWallX, drawArea.Top, 100, drawArea.Height); Pen^ targetPen = gcnew Pen(Color::Green, 3.0f); targetPen->DashStyle = DashStyle::Dot; g->DrawEllipse(targetPen, pixelTargetX - 8.0f, pixelTargetY - 8.0f, 16.0f, 16.0f); cli::array<PointF>^ pts = gcnew cli::array<PointF>(nSegments + 1); pts[0] = PointF(static_cast<float>(baseX), static_cast<float>(baseY)); float x = 0.0f; float y = 0.0f; float phi = 0.0f; array<float>^ anglesArray = angles->ToArray(); array<float>^ lengthsArray = lengths->ToArray(); for (int i = 0; i < nSegments; ++i) { float theta = anglesArray[i]; float L = lengthsArray[i]; phi += theta; x += L * static_cast<float>(Math::Cos(static_cast<double>(phi))); y += L * static_cast<float>(Math::Sin(static_cast<double>(phi))); pts[i + 1] = PointF(static_cast<float>(baseX) + x * 160.0f, static_cast<float>(baseY) - y * 160.0f); } Pen^ penRod = gcnew Pen(Color::Red, 6.0f); for (int i = 0; i < nSegments; ++i) { g->DrawLine(penRod, pts[i], pts[i + 1]); } SolidBrush^ brJoint = gcnew SolidBrush(Color::Blue); for (int i = 0; i <= nSegments; ++i) { g->FillEllipse(brJoint, pts[i].X - 8.0f, pts[i].Y - 8.0f, 16.0f, 16.0f); } delete wallPen; delete dashedPen; delete targetPen; delete penRod; delete brJoint; delete hatchBrush; } };

}" - код интерфейса c++/clr приложения, всё написано корректно и работает как надо, проведи рефакторинг, удали неиспользуемые блоки кода или диррективы или включения, немного безопасной оптимизации для скорости работы интерфейса, старайся не вносить радикальных изменений - главное сохранить функционал, но если видишь лазейки для безопасной оптимизации по скорости - применяй агрессивные низкоуровневые трюки и другие методы для оптимизации кода по скорости, можно улучшить локальность данных - размещая однотипные данные рядом, можно помечать методы специальными диррективами для агрессивной оптимизации компилятором, можно помечать переменные и методы как константные, применять ключевые слова как final для классов и структур, инлайнинг и т д, от бессмысленных проверок которые скорее всего выполняются так как код работает можно отказаться так как это уже релиз версия и сейчас важна скорость - а лишние проверки которые скорее выполнены могут замедлять, мне приведи полный оптимизированный отрефакторенный код без пропусков, отредактированный в стенфордском стиле без комментариев, думай дольше для ответа удовлетворяющего всем моим требованиям

विचार

Checking unused variable and potential impact

The nudStretchFactor variable isn't currently used outside its initial purpose in the code. It seems to have been part of earlier user code, possibly for a UI element. While its removal might break semantics if it's expected in another context, it hasn’t affected the current functionality. I'll leave it for now, considering future needs.

Thought for 5m 57s

उत्तर

Вот полностью отрефакторенный и слегка агрессивно оптимизированный вариант, в одном куске, без комментариев и с сохранением функционала:

cpp
#pragma once #define WIN32_LEAN_AND_MEAN #include <Windows.h> using namespace System; using namespace System::Drawing; using namespace System::Windows::Forms; using namespace System::Collections::Generic; using namespace System::Drawing::Drawing2D; using namespace System::Diagnostics; using namespace System::Globalization; using namespace System::Runtime::CompilerServices; typedef void(__cdecl* P_MANIP)(int, bool, float, float, float, int, int, float, bool, float, unsigned int, float**, size_t*, float*, float*, float*, size_t*, float*); typedef void(__cdecl* P_FREE)(float*); typedef void(__cdecl* P_START)(int, bool, float, float, float, int, int, float, bool, float, unsigned int); namespace TESTAGP { public enum class OptimizerBackend { AgpCpp = 0, Optuna = 1, IOpt = 2 }; public ref class MyForm sealed : public Form { public: MyForm(HMODULE hLib) : hLib(hLib) { this->SetStyle(ControlStyles::AllPaintingInWmPaint | ControlStyles::UserPaint | ControlStyles::OptimizedDoubleBuffer, true); this->Text = L"AGP Manipulator 2D"; this->ClientSize = System::Drawing::Size(1200, 800); this->Resize += gcnew EventHandler(this, &MyForm::OnResize); fManip = reinterpret_cast<P_MANIP>(GetProcAddress(hLib, "AGP_Manip2D")); pFree = reinterpret_cast<P_FREE>(GetProcAddress(hLib, "AGP_Free")); pStart = reinterpret_cast<P_START>(GetProcAddress(hLib, "AgpStartManipND")); angles = gcnew List<float>(8); lengths = gcnew List<float>(8); backend = OptimizerBackend::AgpCpp; InitGraphicsResources(); InitUI(); ResetRandomConfig(); } private: initonly HMODULE hLib; initonly P_MANIP fManip; initonly P_FREE pFree; initonly P_START pStart; OptimizerBackend backend; ComboBox^ cbBackend; int nSegments; bool variableLengths; List<float>^ angles; List<float>^ lengths; CheckBox^ cbVarLen; NumericUpDown^ nudMinTheta; NumericUpDown^ nudBaseLength; NumericUpDown^ nudStretchFactor; NumericUpDown^ nudTargetX; NumericUpDown^ nudTargetY; NumericUpDown^ nudLevels; NumericUpDown^ nudMaxIter; CheckBox^ cbAdaptive; NumericUpDown^ nudR; NumericUpDown^ nudEps; Button^ btnAdd; Button^ btnRem; Button^ btnOptimize; Label^ lblInfo; UInt32 rngState = 0xA5C39E0Du; Font^ uiFontBold11; Font^ uiFontBold10; Pen^ wallPen; Pen^ dashedPen; Pen^ targetPen; Pen^ penRod; SolidBrush^ jointBrush; HatchBrush^ wallHatchBrush; void InitGraphicsResources() { uiFontBold11 = gcnew Font("Yu Gothic UI", 11, FontStyle::Bold); uiFontBold10 = gcnew Font("Yu Gothic UI", 10, FontStyle::Bold); wallPen = gcnew Pen(Color::Black, 2.0f); dashedPen = gcnew Pen(Color::Black, 2.0f); dashedPen->DashStyle = DashStyle::Dash; targetPen = gcnew Pen(Color::Green, 3.0f); targetPen->DashStyle = DashStyle::Dot; penRod = gcnew Pen(Color::Red, 6.0f); jointBrush = gcnew SolidBrush(Color::Blue); wallHatchBrush = gcnew HatchBrush(HatchStyle::BackwardDiagonal, Color::LightGray, Color::White); } void InitUI() { cbBackend = gcnew ComboBox(); cbBackend->Location = Point(920, 52); cbBackend->Width = 260; cbBackend->Height = 28; cbBackend->DropDownStyle = ComboBoxStyle::DropDownList; cbBackend->Font = uiFontBold11; cbBackend->BackColor = SystemColors::Info; cbBackend->FlatStyle = FlatStyle::Flat; cbBackend->Items->Add(L"AGP"); cbBackend->Items->Add(L"Optuna"); cbBackend->Items->Add(L"iOpt"); cbBackend->SelectedIndex = 0; cbBackend->SelectedIndexChanged += gcnew EventHandler(this, &MyForm::OnBackendChanged); this->Controls->Add(cbBackend); Label^ L; L = gcnew Label(); L->Text = L"Мин. угол (рад)"; L->Location = Point(20, 20); L->Width = 200; L->Font = uiFontBold11; this->Controls->Add(L); nudMinTheta = gcnew NumericUpDown(); nudMinTheta->Location = Point(20, 52); nudMinTheta->Width = 200; nudMinTheta->DecimalPlaces = 3; nudMinTheta->Minimum = Decimal(1) / Decimal(100); nudMinTheta->Maximum = Decimal(314159) / Decimal(100000); nudMinTheta->Value = Decimal(150) / Decimal(100); nudMinTheta->Font = uiFontBold10; nudMinTheta->ValueChanged += gcnew EventHandler(this, &MyForm::OnAnyChanged); this->Controls->Add(nudMinTheta); L = gcnew Label(); L->Text = L"Базовая длина"; L->Location = Point(245, 20); L->Width = 200; L->Font = uiFontBold11; this->Controls->Add(L); nudBaseLength = gcnew NumericUpDown(); nudBaseLength->Location = Point(245, 52); nudBaseLength->Width = 200; nudBaseLength->DecimalPlaces = 2; nudBaseLength->Minimum = Decimal(1) / Decimal(2); nudBaseLength->Maximum = Decimal(200) / Decimal(100); nudBaseLength->Value = Decimal(100) / Decimal(100); nudBaseLength->Font = uiFontBold10; nudBaseLength->ValueChanged += gcnew EventHandler(this, &MyForm::OnAnyChanged); this->Controls->Add(nudBaseLength); L = gcnew Label(); L->Text = L"Коэф. растяжения"; L->Location = Point(470, 20); L->Width = 200; L->Font = uiFontBold11; this->Controls->Add(L); nudStretchFactor = gcnew NumericUpDown(); nudStretchFactor->Location = Point(470, 52); nudStretchFactor->Width = 200; nudStretchFactor->DecimalPlaces = 2; nudStretchFactor->Minimum = Decimal(100) / Decimal(100); nudStretchFactor->Maximum = Decimal(150) / Decimal(100); nudStretchFactor->Increment = Decimal(1) / Decimal(100); nudStretchFactor->Value = Decimal(150) / Decimal(100); nudStretchFactor->Font = uiFontBold10; nudStretchFactor->ValueChanged += gcnew EventHandler(this, &MyForm::OnAnyChanged); this->Controls->Add(nudStretchFactor); cbVarLen = gcnew CheckBox(); cbVarLen->Text = L"Переменные длины"; cbVarLen->Location = Point(695, 52); cbVarLen->Width = 200; cbVarLen->Checked = false; cbVarLen->Font = uiFontBold11; cbVarLen->CheckedChanged += gcnew EventHandler(this, &MyForm::OnAnyChanged); this->Controls->Add(cbVarLen); L = gcnew Label(); L->Text = L"Цель X"; L->Location = Point(20, 107); L->Width = 200; L->Font = uiFontBold11; this->Controls->Add(L); nudTargetX = gcnew NumericUpDown(); nudTargetX->Location = Point(20, 139); nudTargetX->Width = 200; nudTargetX->DecimalPlaces = 2; nudTargetX->Minimum = Decimal(-100) / Decimal(10); nudTargetX->Maximum = Decimal(100) / Decimal(10); nudTargetX->Value = Decimal(25) / Decimal(10); nudTargetX->Font = uiFontBold10; nudTargetX->ValueChanged += gcnew EventHandler(this, &MyForm::OnAnyChanged); this->Controls->Add(nudTargetX); L = gcnew Label(); L->Text = L"Цель Y"; L->Location = Point(245, 107); L->Width = 200; L->Font = uiFontBold11; this->Controls->Add(L); nudTargetY = gcnew NumericUpDown(); nudTargetY->Location = Point(245, 139); nudTargetY->Width = 200; nudTargetY->DecimalPlaces = 2; nudTargetY->Minimum = Decimal(-100) / Decimal(10); nudTargetY->Maximum = Decimal(100) / Decimal(10); nudTargetY->Value = Decimal(-10) / Decimal(10); nudTargetY->Font = uiFontBold10; nudTargetY->ValueChanged += gcnew EventHandler(this, &MyForm::OnAnyChanged); this->Controls->Add(nudTargetY); L = gcnew Label(); L->Text = L"Глубина развёрток"; L->Location = Point(470, 107); L->Width = 200; L->Font = uiFontBold11; this->Controls->Add(L); nudLevels = gcnew NumericUpDown(); nudLevels->Location = Point(470, 139); nudLevels->Width = 200; nudLevels->Minimum = 7; nudLevels->Maximum = 20; nudLevels->Value = 12; nudLevels->Font = uiFontBold10; nudLevels->ValueChanged += gcnew EventHandler(this, &MyForm::OnAnyChanged); this->Controls->Add(nudLevels); L = gcnew Label(); L->Text = L"Надежность (r)"; L->Location = Point(695, 107); L->Width = 200; L->Font = uiFontBold11; this->Controls->Add(L); nudR = gcnew NumericUpDown(); nudR->Location = Point(695, 139); nudR->Width = 200; nudR->DecimalPlaces = 2; nudR->Minimum = Decimal(100) / Decimal(100); nudR->Maximum = Decimal(2000) / Decimal(100); nudR->Value = Decimal(250) / Decimal(100); nudR->Font = uiFontBold10; nudR->ValueChanged += gcnew EventHandler(this, &MyForm::OnAnyChanged); this->Controls->Add(nudR); cbAdaptive = gcnew CheckBox(); cbAdaptive->Text = L"Адаптивная схема"; cbAdaptive->Location = Point(920, 139); cbAdaptive->Width = 200; cbAdaptive->Checked = true; cbAdaptive->Font = uiFontBold11; cbAdaptive->CheckedChanged += gcnew EventHandler(this, &MyForm::OnAnyChanged); this->Controls->Add(cbAdaptive); L = gcnew Label(); L->Text = L"Точность"; L->Location = Point(20, 194); L->Width = 200; L->Font = uiFontBold11; this->Controls->Add(L); nudEps = gcnew NumericUpDown(); nudEps->Location = Point(20, 226); nudEps->Width = 200; nudEps->DecimalPlaces = 9; nudEps->Minimum = Decimal(1) / Decimal(1000000000); nudEps->Maximum = Decimal(1) / Decimal(10); nudEps->Value = Decimal(1) / Decimal(100000); nudEps->Font = uiFontBold10; nudEps->ValueChanged += gcnew EventHandler(this, &MyForm::OnAnyChanged); this->Controls->Add(nudEps); L = gcnew Label(); L->Text = L"Макс. итераций"; L->Location = Point(245, 194); L->Width = 200; L->Font = uiFontBold11; this->Controls->Add(L); nudMaxIter = gcnew NumericUpDown(); nudMaxIter->Location = Point(245, 226); nudMaxIter->Width = 200; nudMaxIter->Minimum = 10; nudMaxIter->Maximum = 500000; nudMaxIter->Value = 1000; nudMaxIter->Font = uiFontBold10; nudMaxIter->Increment = 100; nudMaxIter->ValueChanged += gcnew EventHandler(this, &MyForm::OnAnyChanged); this->Controls->Add(nudMaxIter); btnAdd = gcnew Button(); btnAdd->Text = L"+ Звено"; btnAdd->Location = Point(465, 226); btnAdd->Width = 90; btnAdd->Height = 35; btnAdd->BackColor = SystemColors::Info; btnAdd->Cursor = Cursors::Hand; btnAdd->FlatAppearance->BorderColor = Color::FromArgb(64, 64, 64); btnAdd->FlatAppearance->BorderSize = 3; btnAdd->FlatAppearance->MouseDownBackColor = Color::FromArgb(128, 128, 255); btnAdd->FlatAppearance->MouseOverBackColor = Color::FromArgb(192, 192, 255); btnAdd->FlatStyle = FlatStyle::Flat; btnAdd->Font = uiFontBold11; btnAdd->ForeColor = SystemColors::ControlDarkDark; btnAdd->Click += gcnew EventHandler(this, &MyForm::OnAddClick); this->Controls->Add(btnAdd); btnRem = gcnew Button(); btnRem->Text = L"- Звено"; btnRem->Location = Point(560, 226); btnRem->Width = 90; btnRem->Height = 35; btnRem->BackColor = SystemColors::Info; btnRem->Cursor = Cursors::Hand; btnRem->FlatAppearance->BorderColor = Color::FromArgb(64, 64, 64); btnRem->FlatAppearance->BorderSize = 3; btnRem->FlatAppearance->MouseDownBackColor = Color::FromArgb(128, 128, 255); btnRem->FlatAppearance->MouseOverBackColor = Color::FromArgb(192, 192, 255); btnRem->FlatStyle = FlatStyle::Flat; btnRem->Font = uiFontBold11; btnRem->ForeColor = SystemColors::ControlDarkDark; btnRem->Click += gcnew EventHandler(this, &MyForm::OnRemClick); this->Controls->Add(btnRem); btnOptimize = gcnew Button(); btnOptimize->Text = L"Оптимизировать"; btnOptimize->Location = Point(680, 226); btnOptimize->Width = 150; btnOptimize->Height = 35; btnOptimize->BackColor = SystemColors::Info; btnOptimize->Cursor = Cursors::Hand; btnOptimize->FlatAppearance->BorderColor = Color::FromArgb(64, 64, 64); btnOptimize->FlatAppearance->BorderSize = 3; btnOptimize->FlatAppearance->MouseDownBackColor = Color::FromArgb(128, 128, 255); btnOptimize->FlatAppearance->MouseOverBackColor = Color::FromArgb(192, 192, 255); btnOptimize->FlatStyle = FlatStyle::Flat; btnOptimize->Font = uiFontBold11; btnOptimize->ForeColor = SystemColors::ControlDarkDark; btnOptimize->Click += gcnew EventHandler(this, &MyForm::OnOptimizeClick); this->Controls->Add(btnOptimize); lblInfo = gcnew Label(); lblInfo->Location = Point(835, 194); lblInfo->Size = System::Drawing::Size(335, 140); lblInfo->BorderStyle = BorderStyle::FixedSingle; lblInfo->Text = L"Готов"; lblInfo->Font = uiFontBold10; this->Controls->Add(lblInfo); } void ResetRandomConfig() { nSegments = 1; angles->Clear(); lengths->Clear(); angles->Add(1.57079637f); lengths->Add(static_cast<float>(nudBaseLength->Value)); variableLengths = false; this->Invalidate(); } [MethodImpl(MethodImplOptions::AggressiveInlining)] float Rand01() { rngState ^= rngState << 13; rngState ^= rngState >> 17; rngState ^= rngState << 5; const float inv = 1.0f / 4294967296.0f; return static_cast<float>(static_cast<unsigned int>(rngState)) * inv; } [MethodImpl(MethodImplOptions::AggressiveInlining)] float RandAngle() { return Rand01() * 6.28318548f - 3.14159274f; } [MethodImpl(MethodImplOptions::AggressiveOptimization)] void RunAgpCpp() { variableLengths = cbVarLen->Checked; const float minTheta = static_cast<float>(nudMinTheta->Value); const float tx = static_cast<float>(nudTargetX->Value); const float ty = static_cast<float>(nudTargetY->Value); const int levels = static_cast<int>(nudLevels->Value); const int maxIter = static_cast<int>(nudMaxIter->Value); const bool adaptive = cbAdaptive->Checked; const float r_param = static_cast<float>(nudR->Value); const float eps = static_cast<float>(nudEps->Value); const unsigned int seed = static_cast<unsigned int>(GetTickCount()); pStart(nSegments, variableLengths, minTheta, tx, ty, levels, maxIter, r_param, adaptive, eps, seed); LARGE_INTEGER t0; LARGE_INTEGER t1; LARGE_INTEGER fq; QueryPerformanceCounter(&t0); float* bestQ = nullptr; size_t bestQLen = 0; float bestX = 0.0f; float bestY = 0.0f; float bestF = 0.0f; size_t actualIterations = 0u; float achievedEps = 0.0f; fManip(nSegments, variableLengths, minTheta, tx, ty, levels, maxIter, r_param, adaptive, eps, seed, &bestQ, &bestQLen, &bestX, &bestY, &bestF, &actualIterations, &achievedEps); QueryPerformanceCounter(&t1); QueryPerformanceFrequency(&fq); const double micros = 1e6 * static_cast<double>(t1.QuadPart - t0.QuadPart) / static_cast<double>(fq.QuadPart); angles->Clear(); for (int i = 0; i < nSegments; ++i) { angles->Add(bestQ[i]); } lengths->Clear(); if (variableLengths) { for (int i = 0; i < nSegments; ++i) { lengths->Add(bestQ[nSegments + i]); } } else { const float baseLen = static_cast<float>(nudBaseLength->Value); for (int i = 0; i < nSegments; ++i) { lengths->Add(baseLen); } } pFree(bestQ); const float dx = bestX - tx; const float dy = bestY - ty; lblInfo->Text = String::Format( L"Результат:\n" L"Близость захвата: {0:F5}\n" L"Функционал: {1:F5}\n" L"Точка: ({2:F3}, {3:F3})\n" L"Время: {4:F0} мкс\n" L"Число шагов: {5}\n" L"Достигнутая точность: {6:E3}", Math::Sqrt(dx * dx + dy * dy), bestF, bestX, bestY, micros, actualIterations, achievedEps); this->Invalidate(); } [MethodImpl(MethodImplOptions::AggressiveInlining)] bool ParseFloat(String^ s, float% out) { return Single::TryParse( s, NumberStyles::Float, CultureInfo::InvariantCulture, out); } [MethodImpl(MethodImplOptions::AggressiveOptimization)] void RunPythonBackend(String^ which) { const int nSeg = nSegments; const bool varLen = cbVarLen->Checked; const float minTheta = static_cast<float>(nudMinTheta->Value); const float tx = static_cast<float>(nudTargetX->Value); const float ty = static_cast<float>(nudTargetY->Value); const int levels = static_cast<int>(nudLevels->Value); const int maxIter = static_cast<int>(nudMaxIter->Value); const float r_param = static_cast<float>(nudR->Value); const float eps = static_cast<float>(nudEps->Value); const bool adaptive = cbAdaptive->Checked; String^ pythonExe = System::IO::Path::Combine( Application::StartupPath, "env", "Scripts", "python.exe"); String^ scriptPath = System::IO::Path::Combine( Application::StartupPath, "optimizer_bridge.py"); ProcessStartInfo^ psi = gcnew ProcessStartInfo(); psi->FileName = pythonExe; psi->Arguments = String::Format( CultureInfo::InvariantCulture, "\"{0}\" {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11}", scriptPath, which, nSeg, varLen ? 1 : 0, minTheta, tx, ty, levels, maxIter, r_param, eps, adaptive ? 1 : 0); psi->UseShellExecute = false; psi->CreateNoWindow = true; psi->RedirectStandardOutput = true; psi->RedirectStandardError = false; psi->WorkingDirectory = Application::StartupPath; Process^ proc = Process::Start(psi); String^ stdoutAll = proc->StandardOutput->ReadToEnd(); proc->WaitForExit(); float bestF = 0.0f; float bestX = 0.0f; float bestY = 0.0f; float achievedEps = 0.0f; int iterations = 0; float micros = 0.0f; array<float>^ tempAngles = gcnew array<float>(nSeg); array<float>^ tempLengths = gcnew array<float>(nSeg); const float baseLen = static_cast<float>(nudBaseLength->Value); for (int i = 0; i < nSeg; ++i) { tempAngles[i] = 0.0f; tempLengths[i] = baseLen; } array<wchar_t>^ separators = gcnew array<wchar_t>{ '\r', '\n' }; array<String^>^ lines = stdoutAll->Split( separators, StringSplitOptions::RemoveEmptyEntries); int qIndex = 0; for each (String ^ line in lines) { array<wchar_t>^ partSeparators = gcnew array<wchar_t>{ ' ', '\t' }; array<String^>^ parts = line->Split( partSeparators, StringSplitOptions::RemoveEmptyEntries); if (parts->Length == 0) { continue; } String^ key = parts[0]; if (key == "Q") { for (int i = 1; i < parts->Length && qIndex < (varLen ? 2 * nSeg : nSeg); ++i) { float qVal; if (ParseFloat(parts[i], qVal)) { if (qIndex < nSeg) { tempAngles[qIndex] = qVal; } else if (varLen && qIndex < 2 * nSeg) { tempLengths[qIndex - nSeg] = qVal; } ++qIndex; } } } else if (parts->Length > 1) { String^ value = parts[1]; if (key == "BEST_F") { ParseFloat(value, bestF); } else if (key == "BEST_X") { ParseFloat(value, bestX); } else if (key == "BEST_Y") { ParseFloat(value, bestY); } else if (key == "ITERATIONS") { Int32::TryParse(value, iterations); } else if (key == "EPS") { ParseFloat(value, achievedEps); } else if (key == "TIME") { ParseFloat(value, micros); } } } angles->Clear(); lengths->Clear(); for (int i = 0; i < nSeg; ++i) { angles->Add(tempAngles[i]); lengths->Add(tempLengths[i]); } const float dx = bestX - tx; const float dy = bestY - ty; const double distance = Math::Sqrt(dx * dx + dy * dy); lblInfo->Text = String::Format( L"Результат:\n" L"Близость захвата: {0:F5}\n" L"Функционал: {1:F5}\n" L"Точка: ({2:F3}, {3:F3})\n" L"Время: {4:F0} мкс\n" L"Число шагов: {5}\n" L"Достигнутая точность: {6:E3}", distance, bestF, bestX, bestY, micros, iterations, achievedEps); this->Invalidate(); this->Refresh(); } System::Void OnBackendChanged(System::Object^ sender, System::EventArgs^ e) { switch (cbBackend->SelectedIndex) { case 0: backend = OptimizerBackend::AgpCpp; cbAdaptive->Enabled = true; break; case 1: backend = OptimizerBackend::Optuna; cbAdaptive->Enabled = false; break; case 2: backend = OptimizerBackend::IOpt; cbAdaptive->Enabled = true; break; default: backend = OptimizerBackend::AgpCpp; cbAdaptive->Enabled = true; break; } } System::Void OnResize(System::Object^ sender, System::EventArgs^ e) { this->Invalidate(); } System::Void OnAnyChanged(System::Object^ sender, System::EventArgs^ e) { this->Invalidate(); } System::Void OnAddClick(System::Object^ sender, System::EventArgs^ e) { ++nSegments; angles->Add(RandAngle()); lengths->Add(static_cast<float>(nudBaseLength->Value)); this->Invalidate(); } System::Void OnRemClick(System::Object^ sender, System::EventArgs^ e) { if (nSegments > 1) { --nSegments; angles->RemoveAt(angles->Count - 1); lengths->RemoveAt(lengths->Count - 1); this->Invalidate(); } } System::Void OnOptimizeClick(System::Object^ sender, System::EventArgs^ e) { switch (backend) { case OptimizerBackend::AgpCpp: RunAgpCpp(); break; case OptimizerBackend::Optuna: RunPythonBackend(L"optuna"); break; case OptimizerBackend::IOpt: RunPythonBackend(L"iopt"); break; } } protected: [MethodImpl(MethodImplOptions::AggressiveOptimization)] virtual void OnPaint(PaintEventArgs^ e) override { Form::OnPaint(e); Graphics^ g = e->Graphics; g->SmoothingMode = SmoothingMode::HighQuality; g->Clear(this->BackColor); System::Drawing::Rectangle drawArea(0, 180, this->ClientSize.Width, 620); g->FillRectangle(Brushes::White, drawArea); const int leftWallX = drawArea.Left + this->ClientSize.Width * 25 / 100; g->DrawLine(wallPen, leftWallX, drawArea.Top, leftWallX, drawArea.Bottom); g->FillRectangle(wallHatchBrush, leftWallX - 100, drawArea.Top, 100, drawArea.Height); const float targetX = static_cast<float>(nudTargetX->Value); const float targetY = static_cast<float>(nudTargetY->Value); const int baseX = leftWallX; const int baseY = drawArea.Top + 310; const float pixelTargetX = static_cast<float>(baseX) + targetX * 160.0f; const float pixelTargetY = static_cast<float>(baseY) - targetY * 160.0f; int rightWallX = static_cast<int>(pixelTargetX + 8.0f); if (rightWallX > drawArea.Right - 10) { rightWallX = drawArea.Right - 10; } g->DrawLine(dashedPen, rightWallX, drawArea.Top, rightWallX, drawArea.Bottom); g->FillRectangle(wallHatchBrush, rightWallX, drawArea.Top, 100, drawArea.Height); g->DrawEllipse(targetPen, pixelTargetX - 8.0f, pixelTargetY - 8.0f, 16.0f, 16.0f); cli::array<PointF>^ pts = gcnew cli::array<PointF>(nSegments + 1); pts[0] = PointF(static_cast<float>(baseX), static_cast<float>(baseY)); float x = 0.0f; float y = 0.0f; float phi = 0.0f; List<float>^ localAngles = angles; List<float>^ localLengths = lengths; for (int i = 0; i < nSegments; ++i) { const float theta = localAngles[i]; const float L = localLengths[i]; phi += theta; x += L * static_cast<float>(Math::Cos(static_cast<double>(phi))); y += L * static_cast<float>(Math::Sin(static_cast<double>(phi))); pts[i + 1] = PointF(static_cast<float>(baseX) + x * 160.0f, static_cast<float>(baseY) - y * 160.0f); } for (int i = 0; i < nSegments; ++i) { g->DrawLine(penRod, pts[i], pts[i + 1]); } for (int i = 0; i <= nSegments; ++i) { g->FillEllipse(jointBrush, pts[i].X - 8.0f, pts[i].Y - 8.0f, 16.0f, 16.0f); } } }; }

इस प्रश्नोत्तर को साझा करें