Advertisement
ArchonHS

B-spline

Nov 11th, 2019
181
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.38 KB | None | 0 0
  1. //----------------------------------------------------
  2. #include "stdafx.h"
  3. #include <Windows.h>
  4. #include <tchar.h>
  5. #include <math.h>
  6. #include <cmath>
  7. #include <iostream>
  8. #include <fstream>
  9. #include <stdio.h>
  10.  
  11. #define MAX 100
  12. #define N 30
  13.  
  14. using namespace std;
  15. static int sx, sy;
  16. const int SCALE = 1000;
  17. const int MARK = 4;
  18.  
  19. void DcInLp(POINT &point) {
  20.     point.x = point.x* SCALE / sx;
  21.     point.y = SCALE - point.y* SCALE / sy;
  22. }
  23. void transform(HDC& hdc)
  24. {
  25.     SetMapMode(hdc, MM_ANISOTROPIC);
  26.     SetWindowExtEx(hdc, SCALE, -SCALE, NULL);
  27.     SetViewportExtEx(hdc, sx, sy, NULL);
  28.     SetViewportOrgEx(hdc, 0, sy, NULL);
  29. }
  30.  
  31. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  32. TCHAR WinName[] = _T("MainFrame");
  33.  
  34. int APIENTRY WinMain(HINSTANCE This, HINSTANCE Prev, LPSTR cmd, int mode) {
  35.     HWND hWnd;  //Дескриптор главного окна программы
  36.     MSG msg;    //Структура для хранения сообщений
  37.     WNDCLASS wc;  //Класс окна
  38.     //Определение класса окон
  39.     wc.hInstance = This;
  40.     wc.lpszClassName = WinName;                  //Имя класса окна
  41.     wc.lpfnWndProc = WndProc;                    //Функция окна
  42.     wc.style = CS_HREDRAW | CS_VREDRAW;          //Стиль окна
  43.     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);  //Стандартная иконка
  44.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);  //Стандартный курсор
  45.     wc.lpszMenuName = NULL;                    //Нет меню
  46.     wc.cbClsExtra = 0;  //Нет дополнительных данных класса
  47.     wc.cbWndExtra = 0;  //Нет дополнительных данных окна
  48.     //Заполнение окна белым цветом
  49.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);  //установка цвета фона
  50.  
  51.     if (!RegisterClass(&wc)) return 0;  //Регистрация класса окна
  52.  
  53.     //Создание окна
  54.     hWnd = CreateWindow(WinName,  //Имя класса окна
  55.         _T("Каркас Windows-приложения"),  //Заголовок окна
  56.         WS_OVERLAPPEDWINDOW,              //Стиль окна
  57.         CW_USEDEFAULT,                    // X
  58.         CW_USEDEFAULT,                    // Y
  59.         CW_USEDEFAULT,                    // Width
  60.         CW_USEDEFAULT,                    // Height
  61.         HWND_DESKTOP,  //Дескриптор родительского окна
  62.         NULL,  //Нет меню
  63.         This,  //Дескриптор приложения
  64.         NULL);  //Дополнительной информации нет
  65.  
  66.     ShowWindow(hWnd, mode);  //Показать окно
  67.  
  68.     //Цикл обработки сообщений
  69.     while (GetMessage(&msg, NULL, 0, 0))  //цикл получения сообщения
  70.     {
  71.         TranslateMessage(&msg);  //Функция трансляции кодов нажатой клавиши
  72.         DispatchMessage(&msg);  //Посылает сообщение функции WndProc()
  73.     }
  74.     return 0;
  75. }
  76.  
  77. //Оконная функция вызываемая операционной системой
  78. //и получает сообщения из очереди для данного приложения
  79. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {//обработчик сообщений
  80.     PAINTSTRUCT ps;
  81.     static HBRUSH hBrush;
  82.     static HPEN hDash, hBezier; // два пера
  83.     static HBRUSH hRect, hSel; // две кисти
  84.     static POINT pt[20]; // массив хранения плоских точек
  85.     static POINT point; // структура под одну плоскую точку
  86.     RECT rt; // структура точек прямоугольника
  87.     static int count, index; // счётчик точек,
  88.     static bool capture; // логическая переменная для мыши
  89.     float x[MAX], y[MAX], eps = 0.04, X, Y, t, xA, xB, xC, xD,
  90.         yA, yB, yC, yD, a0, a1, a2, a3, b0, b1, b2, b3;
  91.     int n, i, j, first;
  92.     ifstream in; //класс файлового потокового ввода-вывода
  93.     ofstream out;
  94.     HDC hdc;
  95.     switch (message)
  96.     {
  97.     case WM_CREATE:
  98.         in.open("dat.txt"); // открытие файлового потока
  99.         if (in.fail()) {
  100.             MessageBox(hWnd, _T("Файл dat.txt не найден"),
  101.                 _T("Открытие файла"), MB_OK | MB_ICONEXCLAMATION);
  102.             PostQuitMessage(0);
  103.             return 1;
  104.         }
  105.         for (count = 0; in >> pt[count].x; count++)in >> pt[count].y;
  106.         in.close();
  107.         hDash = CreatePen(PS_DASH, 1, 0);
  108.         hBezier = CreatePen(PS_SOLID, 4, RGB(0, 0, 255));
  109.         hRect = CreateSolidBrush(RGB(128, 0, 128));
  110.         hSel = CreateSolidBrush(RGB(255, 0, 0));
  111.         break;
  112.     case WM_SIZE:
  113.         sx = LOWORD(lParam);//Ширина
  114.         sy = HIWORD(lParam);//Высота
  115.         break;
  116.     case WM_LBUTTONDOWN:
  117.         point.x = LOWORD(lParam);
  118.         point.y = HIWORD(lParam);
  119.         DcInLp(point);
  120.         for (i = 0; i <= count; i++) {
  121.             SetRect(&rt, pt[i].x - MARK, pt[i].y - MARK, pt[i].x + MARK, pt[i].y + MARK);
  122.             if (PtInRect(&rt, point)) {
  123.                 index = i;
  124.                 capture = true;
  125.                 hdc = GetDC(hWnd);
  126.                 transform(hdc); //Переход в логические координаты
  127.                 FillRect(hdc, &rt, hSel);//Отметим прямоугольник цветом
  128.                 ReleaseDC(hWnd, hdc);
  129.                 SetCapture(hWnd);
  130.                 return 0;
  131.             }
  132.         }
  133.         break;
  134.     case WM_LBUTTONUP:
  135.         if (capture) {
  136.             ReleaseCapture();
  137.             capture = false;
  138.         }
  139.         break;
  140.     case WM_MOUSEMOVE:
  141.         if (capture) {
  142.             point.x = LOWORD(lParam);
  143.             point.y = HIWORD(lParam);
  144.             DcInLp(point);
  145.             pt[index] = point;
  146.             InvalidateRect(hWnd, NULL, TRUE);
  147.         }
  148.         break;
  149.     case WM_PAINT:
  150.         hdc = BeginPaint(hWnd, &ps);//Установка режима
  151.         transform(hdc);
  152.         SelectObject(hdc, hDash);
  153.         Polyline(hdc, pt, count);
  154.         SelectObject(hdc, hBezier);
  155.         PolyBezier(hdc, pt, count);
  156.         for (int i = 0; i < count; i++) {
  157.             SetRect(&rt, pt[i].x - MARK, pt[i].y - MARK, pt[i].x + MARK, pt[i].y + MARK);
  158.             //FillRect(hdc, &rt, hRect);
  159.             SelectObject(hdc, hBrush);
  160.             MoveToEx(hdc, pt[i].x - MARK, pt[i].y - MARK, NULL);
  161.             LineTo(hdc, pt[i].x + MARK, pt[i].y + MARK);
  162.             MoveToEx(hdc, pt[i].x - MARK, pt[i].y + MARK, NULL);
  163.             LineTo(hdc, pt[i].x + MARK, pt[i].y - MARK);
  164.             n = count;
  165.         }
  166.         for (i = 0; i <= n; i++)
  167.         {
  168.             X = pt[i].x; Y = pt[i].y;
  169.             MoveToEx(hdc, X - eps, Y - eps, NULL); LineTo(hdc, X + eps, Y + eps);
  170.             MoveToEx(hdc, X + eps, Y - eps, NULL); LineTo(hdc, X - eps, Y + eps);
  171.         }
  172.         first = 1;
  173.         for (i = 1; i < n - 2; i++)
  174.         {
  175.             xA = pt[i - 1].x; xB = pt[i].x; xC = pt[i + 1].x; xD = pt[i + 2].x;
  176.          yA = pt[i - 1].y; yB = pt[i].y; yC = pt[i + 1].y; yD = pt[i + 2].y;
  177.          a3 = (-xA + 3 * (xB - xC) + xD) / 6.0; b3 = (-yA + 3 * (yB - yC) + yD) / 6.0;
  178.          a2 = (xA - 2 * xB + xC) / 2.0; b2 = (yA - 2 * yB + yC) / 2.0;
  179.          a1 = (xC - xA) / 2.0; b1 = (yC - yA) / 2.0;
  180.          a0 = (xA + 4 * xB + xC) / 6.0; b0 = (yA + 4 * yB + yC) / 6.0;
  181.          for (j = 0; j <= N; j++)
  182.          {
  183.          t = (float)j / (float)N;
  184.         X = ((a3*t + a2)*t + a1)*t + a0;
  185.         Y = ((b3*t + b2)*t + b1)*t + b0;
  186.         if(first) { first = 0; MoveToEx(hdc, X, Y, NULL); }
  187.          else LineTo(hdc, X, Y);
  188. }
  189.             }
  190.         break;
  191.     case WM_DESTROY:
  192.         DeleteObject(hDash);
  193.         DeleteObject(hBezier);
  194.         DeleteObject(hRect);
  195.         DeleteObject(hSel);
  196.         out.open("dat.txt");
  197.         for (int i = 0; i < count; i++)out << pt[i].x << '\t' << pt[i].y << '\n';
  198.         out.close();
  199.         EndPaint(hWnd, &ps);
  200.         PostQuitMessage(0);
  201.         break;
  202.     default:return DefWindowProc(hWnd, message, wParam, lParam);
  203.     }
  204.     return 0;
  205. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement