Advertisement
sir_timyp

курсач

May 21st, 2019
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 15.68 KB | None | 0 0
  1. // Win32Project1.cpp: определяет точку входа для приложения.
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "Win32Project1.h"
  6. #include <stdio.h>
  7. #include <Math.h>
  8.  
  9.  
  10. #define MAX_LOADSTRING 100
  11.  
  12. // Глобальные переменные:
  13. HINSTANCE hInst;                                // текущий экземпляр
  14. TCHAR szTitle[MAX_LOADSTRING];                  // Текст строки заголовка
  15. TCHAR szWindowClass[MAX_LOADSTRING];            // имя класса главного окна
  16.  
  17. // Отправить объявления функций, включенных в этот модуль кода:
  18. ATOM                MyRegisterClass(HINSTANCE hInstance);
  19. BOOL                InitInstance(HINSTANCE, int);
  20. LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
  21. INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
  22.  
  23. int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
  24.                      _In_opt_ HINSTANCE hPrevInstance,
  25.                      _In_ LPTSTR    lpCmdLine,
  26.                      _In_ int       nCmdShow)
  27. {
  28.     UNREFERENCED_PARAMETER(hPrevInstance);
  29.     UNREFERENCED_PARAMETER(lpCmdLine);
  30.  
  31.     // TODO: разместите код здесь.
  32.     MSG msg;
  33.    
  34.     // Инициализация глобальных строк
  35.     LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
  36.     LoadString(hInstance, IDC_WIN32PROJECT1, szWindowClass, MAX_LOADSTRING);
  37.     MyRegisterClass(hInstance);
  38.  
  39.     // Выполнить инициализацию приложения:
  40.     if (!InitInstance (hInstance, nCmdShow))
  41.     {
  42.         return FALSE;
  43.     }
  44.  
  45.  
  46.     // Цикл основного сообщения:
  47.     while (GetMessage(&msg, NULL, 0, 0))
  48.     {
  49.             TranslateMessage(&msg);
  50.             DispatchMessage(&msg);
  51.     }
  52.  
  53.     return (int) msg.wParam;
  54. }
  55.  
  56. //
  57. //  ФУНКЦИЯ: MyRegisterClass()
  58. //
  59. //  НАЗНАЧЕНИЕ: регистрирует класс окна.
  60. //
  61. ATOM MyRegisterClass(HINSTANCE hInstance)
  62. {
  63.     WNDCLASSEX wcex;
  64.  
  65.     wcex.cbSize = sizeof(WNDCLASSEX);
  66.  
  67.     wcex.style          = CS_HREDRAW | CS_VREDRAW;
  68.     wcex.lpfnWndProc    = WndProc;
  69.     wcex.cbClsExtra     = 0;
  70.     wcex.cbWndExtra     = 0;
  71.     wcex.hInstance      = hInstance;
  72.     wcex.hIcon          = NULL;
  73.     wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
  74.     wcex.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 13);
  75.     wcex.lpszMenuName   = NULL;
  76.     wcex.lpszClassName  = szWindowClass;
  77.     wcex.hIconSm        = NULL;
  78.  
  79.     return RegisterClassEx(&wcex);
  80. }
  81.  
  82. //
  83. //   ФУНКЦИЯ: InitInstance(HINSTANCE, int)
  84. //
  85. //   НАЗНАЧЕНИЕ: сохраняет обработку экземпляра и создает главное окно.
  86. //
  87. //   КОММЕНТАРИИ:
  88. //
  89. //        В данной функции дескриптор экземпляра сохраняется в глобальной переменной, а также
  90. //        создается и выводится на экран главное окно программы.
  91. //
  92. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  93. {
  94.    HWND hWnd;
  95.  
  96.    hInst = hInstance; // Сохранить дескриптор экземпляра в глобальной переменной
  97.  
  98.    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
  99.       CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
  100.  
  101.    //HWND button = CreateWindowW(L"BUTTON", L"Сбросить", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 1300, 650, 100, 35, hWnd, (HMENU)101, (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), NULL);
  102.  
  103.    if (!hWnd)
  104.    {
  105.       return FALSE;
  106.    }
  107.  
  108.    ShowWindow(hWnd, nCmdShow);
  109.    UpdateWindow(hWnd);
  110.  
  111.    return TRUE;
  112. }
  113.  
  114. //
  115. //  ФУНКЦИЯ: WndProc(HWND, UINT, WPARAM, LPARAM)
  116. //
  117. //  НАЗНАЧЕНИЕ:  обрабатывает сообщения в главном окне.
  118. //
  119. //  WM_COMMAND  - обработка меню приложения
  120. //  WM_PAINT    -Закрасить главное окно
  121. //  WM_DESTROY   - ввести сообщение о выходе и вернуться.
  122. //
  123. //
  124.  
  125. const int numEdges = 10;  //максимальное количество вершин острова
  126. const int numIslands = 10;  //максимальное количество островов
  127.  
  128. //количество пользовательских островов
  129. //int userIsland = 2;
  130.  
  131. int count = 0;
  132. int countEnteredEdges = 0;
  133. //матрица координат вершин
  134. float islands[numIslands][numEdges][2] = {};
  135. //матрица расстояний до островов
  136. float M[numIslands][numIslands] = {};
  137. //матрица координат мостов
  138. float A[numIslands][numIslands][4] = {};
  139. //покрывающее дерево
  140. int tabu[numIslands][2] = {};
  141.  
  142. //дистанция от точки 1 до точки 2
  143. float Distance(float x1, float y1, float x2, float y2)
  144. {
  145.     return sqrtf((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1));
  146. }
  147. //записывает координаты в матрицу координат вершин островов
  148. void WriteCoord(float x, float y) {
  149.     for (int i = 0; i < numEdges; i++)
  150.     {
  151.         if (islands[count][i][0] <= 0 || islands[count][i][1] <= 0) {
  152.             islands[count][i][0] = x;
  153.             islands[count][i][1] = y;
  154.             break;
  155.         }
  156.     }
  157. }
  158. //проверка на наличие в табу
  159. int HasInTabu(int tabu[][2], int start, int end)
  160. {
  161.     for (int i = 0; i < numIslands; i++)
  162.     {
  163.         if (tabu[i][0] == start && tabu[i][1] == end)
  164.             return 1;
  165.     }
  166.     return 0;
  167. }
  168.  
  169. int TheEnd(int *G, int count)
  170. {
  171.     for (int i = 0; i < count-1; i++)
  172.     {
  173.         if (G[i + 1] != G[i])
  174.             return 0;
  175.     }
  176.     return 1;
  177. }
  178. //округление???
  179. float round(float value){
  180.     return float(int(value*10000))/10000;
  181. }
  182.  
  183. //возвращает 1, если есть точка пересечения перпендикуляра и прямой
  184. int Point(float x1, float y1, float x2, float y2, float x0, float y0, float *x, float *y) {
  185.     float a1, a2, b1, b2, c1, c2;
  186.     a1 = y1 - y2; //x
  187.     b1 = x2 - x1;    //y
  188.     c1 = x1 * y2 - x2 * y1;
  189.  
  190.     a2 = b1;
  191.     b2 = -a1;
  192.     c2 = -(a2 * x0 + b2 * y0);
  193.     float xp, yp;
  194.  
  195.     xp = -((c1 * b2 - c2 * b1) / (a1 * b2 - a2 * b1));
  196.     yp = -((a1 * c2 - a2 * c1) / (a1 * b2 - a2 * b1));
  197.     *x = xp;
  198.     *y = yp;
  199.     //вот тут что то не то
  200.     if ((xp >= min(x1, x2) && xp <= max(x1, x2) && yp >= min(y1, y2) && yp <= max(y1, y2)))
  201.         return round((xp - x1) / (x2 - x1)) == round((yp - y1) / (y2 - y1));
  202.     else
  203.         return 0;
  204. }
  205.  
  206. void Reset()
  207. {
  208.     count = 0;
  209.     countEnteredEdges = 0;
  210.    
  211.     for (int i = 0; i < numIslands; i++)
  212.     {
  213.         for (int j = 0; j < numIslands; j++)
  214.         {
  215.             A[i][j][0] = 0;
  216.             A[i][j][1] = 0;
  217.             A[i][j][2] = 0;
  218.             A[i][j][3] = 0;
  219.         }
  220.     }
  221.  
  222.     for (int i = 0; i < numIslands; i++)
  223.     {
  224.         for (int j = 0; j < numIslands; j++)
  225.         {
  226.             M[i][j] = 0;
  227.         }
  228.     }
  229.    
  230.     for (int i = 0; i < numIslands; i++)
  231.     {
  232.         for (int j = 0; j < numEdges; j++)
  233.         {
  234.             islands[i][j][0] = 0;
  235.             islands[i][j][1] = 0;
  236.         }
  237.     }
  238.    
  239.     for (int i = 0; i < numIslands; i++)
  240.     {
  241.         tabu[i][0] = 0;
  242.         tabu[i][1] = 0;
  243.     }
  244.    
  245. }
  246.  
  247. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  248. {
  249.     int wmId, wmEvent;
  250.     PAINTSTRUCT ps;
  251.     HDC hdc;
  252.    
  253.     switch (message)
  254.     {
  255.     case WM_LBUTTONDOWN:
  256.     {
  257.         float xPos = LOWORD(lParam);
  258.         float yPos = HIWORD(lParam);
  259.         HPEN hpen = CreatePen(PS_SOLID, 2, RGB(255, 0, 0));
  260.         HDC hdc = GetDC(hWnd);
  261.         SelectObject(hdc, hpen);
  262.         MoveToEx(hdc, xPos - 3, yPos - 3, NULL);
  263.         LineTo(hdc, xPos + 3, yPos + 3);
  264.         MoveToEx(hdc, xPos + 3, yPos - 3, NULL);
  265.         LineTo(hdc, xPos - 3, yPos + 3);
  266.         DeleteObject(hpen);
  267.         WriteCoord(xPos, yPos);
  268.         countEnteredEdges++;
  269.         break;
  270.     }
  271.     case WM_KEYDOWN:
  272.     {
  273.         HDC hdc = GetDC(hWnd);
  274.         int code = HIWORD(lParam) % 255 - 1;
  275.        
  276.         HPEN hpen = CreatePen(PS_SOLID, 2, RGB(255, 228, 49));
  277.         SelectObject(hdc, hpen);
  278.         SetTextColor(hdc, RGB(255, 255, 255));//Устанавливаем цвет текст
  279.         SetBkColor(hdc, RGB(51, 153, 255));//Устанавливаем цвет бэкграунда
  280.         if(code == 27 || code == 28){
  281.             if (countEnteredEdges > 0)
  282.             {
  283.                 int x = islands[count][0][0], y = islands[count][0][1];
  284.                 for (int i = 0; i < numEdges - 1; i++)
  285.                 {
  286.                     if (islands[count][i + 1][0] <= 0 && islands[count][i + 1][1] <= 0)
  287.                     {
  288.                         MoveToEx(hdc, islands[count][i][0], islands[count][i][1], NULL);
  289.                         LineTo(hdc, islands[count][0][0], islands[count][0][1]);
  290.                         x = (x + islands[count][1][0]) / 2;
  291.                         y = (y + islands[count][1][1]) / 2;
  292.                         break;
  293.                     }
  294.                     MoveToEx(hdc, islands[count][i][0], islands[count][i][1], NULL);
  295.                     LineTo(hdc, islands[count][i + 1][0], islands[count][i + 1][1]);
  296.                     x = (x + islands[count][i+1][0]) / 2;
  297.                     y = (y + islands[count][i+1][1]) / 2;
  298.                 }
  299.  
  300.                 HBRUSH hBrush = CreateSolidBrush(RGB(240, 219, 125));
  301.                 SelectObject(hdc, hBrush);
  302.                 FloodFill(hdc, x, y, RGB(255, 228, 49));
  303.                 DeleteObject(hBrush);
  304.  
  305.                 countEnteredEdges = 0;
  306.                 count++;
  307.             }
  308.             else
  309.             {
  310.                 int min_i = 0;
  311.                 int min_j = 0;
  312.                 int isP = 0;
  313.                 float minDistance;
  314.  
  315.                 //здесь перпендикуляры найти
  316.                 for (int i = 0; i < count; i++)
  317.                 {
  318.                     int k = 0;
  319.  
  320.                     for (; k < count; k++)
  321.                     {
  322.                         if (k == i)
  323.                             continue;
  324.                        
  325.                         minDistance = Distance(islands[i][0][0], islands[i][0][1], islands[k][0][0], islands[k][0][1]);
  326.  
  327.                         for(int m = 0; m < numEdges; m++)
  328.                         {
  329.                             for(int j = 1; j < numEdges; j++)
  330.                             {
  331.                                 if(islands[k][m][0] && islands[k][m][1] && islands[i][j][0] && islands[i][j][1])
  332.                                 {
  333.                                     float temp = Distance(islands[k][m][0], islands[k][m][1], islands[i][j][0], islands[i][j][1]);
  334.  
  335.                                     if(temp < minDistance)
  336.                                     {
  337.                                         minDistance = temp;
  338.                                         min_j = m;
  339.                                         min_i = j;
  340.                                     }
  341.                                 }
  342.                             }
  343.                         }
  344.  
  345.                         //тут идет проверка на перпендикуляры
  346.                         float x, y;   //точка пересечения прямых
  347.                         float xp, yp;
  348.                         //что-то с матешой не так
  349.                        
  350.  
  351.                         for(int m = 0; m < numEdges; m++)
  352.                         {
  353.                             for(int j = 0; j < numEdges; j++)
  354.                             {
  355.                                 if(islands[k][m][0] && islands[k][m][1])
  356.                                 {
  357.                                     if (islands[i][j + 1][0] && islands[i][j + 1][1])
  358.                                     {
  359.                                         if (Point(islands[i][j][0], islands[i][j][1], islands[i][j + 1][0], islands[i][j + 1][1], islands[k][m][0], islands[k][m][1], &x, &y))
  360.                                         {
  361.                                             float temp = Distance(x, y, islands[k][m][0], islands[k][m][1]);
  362.                                             if (temp < minDistance)
  363.                                             {
  364.                                                 minDistance = temp;
  365.                                                 isP = 1;
  366.                                                 xp = x;
  367.                                                 yp = y;
  368.                                                 min_j = m;
  369.                                             }
  370.                                         }
  371.                                     }
  372.                                     else
  373.                                     {
  374.                                         //проверяем первый и последний
  375.                                         if (Point(islands[i][0][0], islands[i][0][1], islands[i][j][0], islands[i][j][1], islands[k][m][0], islands[k][m][1], &x, &y))
  376.                                         {
  377.                                             float temp = Distance(x, y, islands[k][m][0], islands[k][m][1]);
  378.                                             if (temp < minDistance)
  379.                                             {
  380.                                                 minDistance = temp;
  381.                                                 isP = 1;
  382.                                                 xp = x;
  383.                                                 yp = y;
  384.                                                 min_j = m;
  385.                                             }
  386.                                         }
  387.                                         break;
  388.                                     }
  389.                                 }
  390.                             }
  391.                         }
  392.  
  393.                         M[i][k] = minDistance;
  394.                         A[i][k][2] = islands[k][min_j][0];
  395.                         A[i][k][3] = islands[k][min_j][1];
  396.                        
  397.                         M[i][k] = minDistance;
  398.                         A[i][k][2] = islands[k][min_j][0];
  399.                         A[i][k][3] = islands[k][min_j][1];
  400.                         if (isP)//если есть перпендикуляр
  401.                         {
  402.                            
  403.                             A[i][k][0] = xp;
  404.                             A[i][k][1] = yp;
  405.                         }
  406.                         else
  407.                         {
  408.                             //сделать как М
  409.                             A[i][k][0] = islands[i][min_i][0];
  410.                             A[i][k][1] = islands[i][min_i][1];
  411.                         }
  412.                         isP = 0;
  413.                         min_i = 0;
  414.                         min_j = 0;
  415.                     }
  416.                 }
  417.                 //находим покрывающее дерево
  418.                 //массив компонент связностей
  419.                 int G[numIslands] = {};
  420.                 //назначаем каждой вершине свою компоненту связности
  421.                 for (int i = 0; i < count; i++)
  422.                     G[i] = i;
  423.  
  424.                 //почему то появляется цикл при каких либо тестах
  425.  
  426.                 int n = 0;
  427.                 int a = 0;
  428.                 int b = 0;
  429.                 //int max = count * (count - 1) / 2; //максимальное количество ребер в полном графе
  430.                 float min = 0;
  431.                
  432.                 int max = count - 1;
  433.                 while (n < max)
  434.                 {
  435.                     //находим минимальное ребро для сравнения
  436.                     for (int i = 0; i < count; i++)
  437.                     {
  438.                         for (int j = 0; j < count; j++)
  439.                         {
  440.                             if (M[i][j] > 0 && !HasInTabu(tabu, i, j))
  441.                             {
  442.                                 min = M[i][j];
  443.                                 a = i;
  444.                                 b = j;
  445.                                 break;
  446.                             }
  447.                         }
  448.                         if(min)
  449.                             break;
  450.                     }
  451.                        
  452.                     for (int i = 0; i < count; i++)
  453.                     {
  454.                         for (int j = 0; j < count; j++)
  455.                         {
  456.                             if (M[i][j] > 0 && !HasInTabu(tabu, i, j) && M[i][j] < min)
  457.                             {
  458.                                 min = M[i][j];
  459.                                 a = i;
  460.                                 b = j;
  461.                             }
  462.                         }
  463.                     }
  464.  
  465.                     //если в разных компонентах связности
  466.                     if (G[a] != G[b])
  467.                     {
  468.                         int temp = G[b];
  469.                         for (int i = 0; i < count; i++)
  470.                             if (G[i] == temp) G[i] = G[a];
  471.                        
  472.                         tabu[n][0] = a;
  473.                         tabu[n][1] = b;
  474.                         n++;
  475.                     }
  476.                     else
  477.                     {
  478.                         M[a][b] = 0;
  479.                         M[b][a] = 0;
  480.                     }
  481.                            
  482.                     //нашли минимальное, тогда если существует путь в обратную, то он нам не нужен => обнуляем
  483.                    
  484.                     if(M[a][b] > 0 && M[b][a] > 0)
  485.                     {
  486.                         if(M[a][b] < M[b][a])
  487.                             M[b][a] = 0;
  488.                         else
  489.                             M[a][b] = 0;
  490.                     }
  491.                    
  492.                     if (TheEnd(G, count))
  493.                         break;
  494.                 }
  495.                 int sum = 0;
  496.                 //нужен ли массив А или можно без него как то обойтись?
  497.                 SetTextColor(hdc, RGB(255,255,255));//Устанавливаем цвет текст
  498.                 SetBkColor(hdc, RGB(51,153,255));//Устанавливаем цвет бэкграунда
  499.                 for (int i = 0; i < count; i++)
  500.                 {
  501.                     float x1, x2, y1, y2;
  502.                     x1 = A[tabu[i][0]][tabu[i][1]][0];
  503.                     y1 = A[tabu[i][0]][tabu[i][1]][1];
  504.                     x2 = A[tabu[i][0]][tabu[i][1]][2];
  505.                     y2 = A[tabu[i][0]][tabu[i][1]][3];
  506.                     MoveToEx(hdc, x1, y1, NULL);
  507.                     LineTo(hdc, x2, y2);
  508.                     //TextOut(hdc, 50, 150, L"1," ,3);
  509.                     DeleteObject(hpen);
  510.                    
  511.                     int dist = Distance(x1, y1, x2, y2);
  512.                     char distance[20];
  513.                     _itoa_s(dist, distance, 10);
  514.                     wchar_t temp[20];
  515.                     mbstowcs(temp, distance, 5);
  516.                     sum += dist;
  517.                     TextOut(hdc, (x2 + x1) / 2, (y1 + y2) / 2, temp, strlen(distance));
  518.                 }
  519.                 char num[10];
  520.                 _itoa_s(sum, num, 10);
  521.                 char text[30] = "Summa: ";
  522.                 strcat_s(text, num);
  523.                 wchar_t temp[255];
  524.                 mbstowcs(temp, text, 30);
  525.  
  526.                 TextOut(hdc, 5, 500, temp, strlen(text));
  527.                
  528.                 break;
  529.             }
  530.         }
  531.         if(code == 18)
  532.         {
  533.             HDC hdc = GetDC(hWnd);
  534.                 HBRUSH hBrush = CreateSolidBrush(RGB(51, 153, 255));
  535.                 SelectObject(hdc, hBrush);
  536.                 Reset();
  537.                 FloodFill(hdc, 0, 0, RGB(0, 0, 0));
  538.                 DeleteObject(hBrush);
  539.         }
  540.     }
  541.  
  542.     case WM_PAINT:
  543.         hdc = BeginPaint(hWnd, &ps);
  544.         // TODO: добавьте любой код отрисовки...
  545.        
  546.         TextOut(hdc, 5, 700, L"Нажмите R для сброса значений", 29);
  547.         //SetTextColor(hdc, COLOR_GRAYTEXT + 4);
  548.         EndPaint(hWnd, &ps);
  549.         break;
  550. /*
  551.     case WM_COMMAND:
  552.     {
  553.         switch (LOWORD(wParam))
  554.         {
  555.             case 101:
  556.             {
  557.                 HDC hdc = GetDC(hWnd);
  558.                 HBRUSH hBrush = CreateSolidBrush(RGB(51, 153, 255));
  559.                 SelectObject(hdc, hBrush);
  560.                 Reset();
  561.                 FloodFill(hdc, 0, 0, RGB(0, 0, 0));
  562.                 DeleteObject(hBrush);
  563.             }
  564.         }
  565.         break;
  566.     }
  567.     */
  568.     case WM_DESTROY:
  569.         PostQuitMessage(0);
  570.         break;
  571.     default:
  572.         return DefWindowProc(hWnd, message, wParam, lParam);
  573.     }
  574.     return 0;
  575. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement