Advertisement
Guest User

Untitled

a guest
May 26th, 2016
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.80 KB | None | 0 0
  1. // Mebius.cpp: определяет точку входа для приложения.
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "Mebius.h"
  6. #define _USE_MATH_DEFINES
  7. #include <cmath>
  8.  
  9. const int Z_SIZE = 2000;
  10. double z_buffer[Z_SIZE][Z_SIZE];
  11.  
  12. #define MAX_LOADSTRING 100
  13. //#define ISOMETRIC
  14.  
  15. void proj(double x, double y, double z, double &xx, double &yy) {
  16. #ifdef ISOMETRIC
  17. xx = (y - x) * sqrt(3) / 2.0;
  18. yy = (x + y) / 2.0 - z;
  19. #else
  20. xx = -x / (2.0 * sqrt(2)) + y;
  21. yy = x / (2.0 * sqrt(2)) - z;
  22. #endif
  23. }
  24.  
  25. void Mebius(double u, double v, double R, double W, double &x, double &y, double &z) {
  26. x = (R + v / 2.0 * cos(u / 2.0)) * cos(u);
  27. y = (R + v / 2.0 * cos(u / 2.0)) * sin(u);
  28. z = v / 2.0 * sin(u / 2.0);
  29. }
  30.  
  31. double n_x(double R, double u, double v) {
  32.  
  33. double x_result;
  34. x_result = -1.0L / 2.0L*R*pow(sin(u), 2)*cos((1.0L / 2.0L)*u) - 1.0L / 2.0L*R*cos((1.0L / 2.0L)*u)*pow(cos(u), 2) - 1.0L / 4.0L*v*pow(sin(u), 2)*pow(cos((1.0L / 2.0L)*u), 2) - 1.0L / 4.0L*v*pow(cos((1.0L / 2.0L)*u), 2)*pow(cos(u), 2);
  35. return x_result;
  36.  
  37. }
  38.  
  39. double n_y(double R, double u, double v) {
  40.  
  41. double y_result;
  42. y_result = (1.0L / 2.0L)*R*sin((1.0L / 2.0L)*u)*cos(u) - 1.0L / 8.0L*v*pow(sin((1.0L / 2.0L)*u), 2)*sin(u) + (1.0L / 4.0L)*v*sin((1.0L / 2.0L)*u)*cos((1.0L / 2.0L)*u)*cos(u) - 1.0L / 8.0L*v*sin(u)*pow(cos((1.0L / 2.0L)*u), 2);
  43. return y_result;
  44.  
  45. }
  46.  
  47. double n_z(double R, double u, double v) {
  48.  
  49. double z_result;
  50. z_result = (1.0L / 2.0L)*R*sin((1.0L / 2.0L)*u)*sin(u) + (1.0L / 8.0L)*v*pow(sin((1.0L / 2.0L)*u), 2)*cos(u) + (1.0L / 4.0L)*v*sin((1.0L / 2.0L)*u)*sin(u)*cos((1.0L / 2.0L)*u) + (1.0L / 8.0L)*v*pow(cos((1.0L / 2.0L)*u), 2)*cos(u);
  51. return z_result;
  52.  
  53. }
  54.  
  55. // Глобальные переменные:
  56. HINSTANCE hInst; // текущий экземпляр
  57. TCHAR szTitle[MAX_LOADSTRING]; // Текст строки заголовка
  58. TCHAR szWindowClass[MAX_LOADSTRING]; // имя класса главного окна
  59.  
  60. // Отправить объявления функций, включенных в этот модуль кода:
  61. ATOM MyRegisterClass(HINSTANCE hInstance);
  62. BOOL InitInstance(HINSTANCE, int);
  63. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  64. INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
  65.  
  66. int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
  67. _In_opt_ HINSTANCE hPrevInstance,
  68. _In_ LPTSTR lpCmdLine,
  69. _In_ int nCmdShow)
  70. {
  71. UNREFERENCED_PARAMETER(hPrevInstance);
  72. UNREFERENCED_PARAMETER(lpCmdLine);
  73.  
  74. // TODO: разместите код здесь.
  75. MSG msg;
  76. HACCEL hAccelTable;
  77.  
  78. // Инициализация глобальных строк
  79. LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
  80. LoadString(hInstance, IDC_MEBIUS, szWindowClass, MAX_LOADSTRING);
  81. MyRegisterClass(hInstance);
  82.  
  83. // Выполнить инициализацию приложения:
  84. if (!InitInstance (hInstance, nCmdShow))
  85. {
  86. return FALSE;
  87. }
  88.  
  89. hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MEBIUS));
  90.  
  91. // Цикл основного сообщения:
  92. while (GetMessage(&msg, NULL, 0, 0))
  93. {
  94. if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
  95. {
  96. TranslateMessage(&msg);
  97. DispatchMessage(&msg);
  98. }
  99. }
  100.  
  101. return (int) msg.wParam;
  102. }
  103.  
  104.  
  105.  
  106. //
  107. // ФУНКЦИЯ: MyRegisterClass()
  108. //
  109. // НАЗНАЧЕНИЕ: регистрирует класс окна.
  110. //
  111. ATOM MyRegisterClass(HINSTANCE hInstance)
  112. {
  113. WNDCLASSEX wcex;
  114.  
  115. wcex.cbSize = sizeof(WNDCLASSEX);
  116.  
  117. wcex.style = CS_HREDRAW | CS_VREDRAW;
  118. wcex.lpfnWndProc = WndProc;
  119. wcex.cbClsExtra = 0;
  120. wcex.cbWndExtra = 0;
  121. wcex.hInstance = hInstance;
  122. wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MEBIUS));
  123. wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
  124. wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  125. wcex.lpszMenuName = MAKEINTRESOURCE(IDC_MEBIUS);
  126. wcex.lpszClassName = szWindowClass;
  127. wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
  128.  
  129. return RegisterClassEx(&wcex);
  130. }
  131.  
  132. //
  133. // ФУНКЦИЯ: InitInstance(HINSTANCE, int)
  134. //
  135. // НАЗНАЧЕНИЕ: сохраняет обработку экземпляра и создает главное окно.
  136. //
  137. // КОММЕНТАРИИ:
  138. //
  139. // В данной функции дескриптор экземпляра сохраняется в глобальной переменной, а также
  140. // создается и выводится на экран главное окно программы.
  141. //
  142. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  143. {
  144. HWND hWnd;
  145.  
  146. hInst = hInstance; // Сохранить дескриптор экземпляра в глобальной переменной
  147.  
  148. hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
  149. CW_USEDEFAULT, 0, 1000, 1000, NULL, NULL, hInstance, NULL);
  150.  
  151. if (!hWnd)
  152. {
  153. return FALSE;
  154. }
  155.  
  156. ShowWindow(hWnd, nCmdShow);
  157. UpdateWindow(hWnd);
  158.  
  159. return TRUE;
  160. }
  161.  
  162. //
  163. // ФУНКЦИЯ: WndProc(HWND, UINT, WPARAM, LPARAM)
  164. //
  165. // НАЗНАЧЕНИЕ: обрабатывает сообщения в главном окне.
  166. //
  167. // WM_COMMAND - обработка меню приложения
  168. // WM_PAINT -Закрасить главное окно
  169. // WM_DESTROY - ввести сообщение о выходе и вернуться.
  170. //
  171. //
  172. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  173. {
  174. int wmId, wmEvent;
  175. PAINTSTRUCT ps;
  176. HDC hdc;
  177. RECT rect;
  178. GetClientRect(hWnd, &rect);
  179. const int w = rect.right - rect.left;
  180. const int T = 2000;
  181. const int h = rect.bottom - rect.top;
  182. const int u_size = 30;
  183. const int v_size = 10;
  184.  
  185. int X, Y, X0, Y0;
  186. double R = 2.0, W = .8;
  187. double u, v, x, y, z, xx, yy, nx, ny, nz;
  188. double prev_x, prev_y, prev_z;
  189. double const L = 3.0;
  190. double max_xx = L, max_yy = L, min_xx = -L, min_yy = -L;
  191.  
  192.  
  193. switch (message)
  194. {
  195. case WM_COMMAND:
  196. wmId = LOWORD(wParam);
  197. wmEvent = HIWORD(wParam);
  198. // Разобрать выбор в меню:
  199. switch (wmId)
  200. {
  201. case IDM_ABOUT:
  202. DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
  203. break;
  204. case IDM_EXIT:
  205. DestroyWindow(hWnd);
  206. break;
  207. default:
  208. return DefWindowProc(hWnd, message, wParam, lParam);
  209. }
  210. break;
  211. case WM_PAINT:
  212. hdc = BeginPaint(hWnd, &ps);
  213. // TODO: добавьте любой код отрисовки...
  214. proj(0, 0, 0, xx, yy);
  215. X0 = w * (xx - min_xx) / (max_xx - min_xx);
  216. Y0 = h * (yy - min_yy) / (max_yy - min_yy);
  217.  
  218. proj(1, 0, 0, xx, yy);
  219. X = w * (xx - min_xx) / (max_xx - min_xx);
  220. Y = h * (yy - min_yy) / (max_yy - min_yy);
  221. MoveToEx(hdc, X0, Y0, NULL); LineTo(hdc, X, Y);
  222.  
  223. proj(0, 1, 0, xx, yy);
  224. X = w * (xx - min_xx) / (max_xx - min_xx);
  225. Y = h * (yy - min_yy) / (max_yy - min_yy);
  226. MoveToEx(hdc, X0, Y0, NULL); LineTo(hdc, X, Y);
  227.  
  228. proj(0, 0, 1, xx, yy);
  229. X = w * (xx - min_xx) / (max_xx - min_xx);
  230. Y = h * (yy - min_yy) / (max_yy - min_yy);
  231. MoveToEx(hdc, X0, Y0, NULL); LineTo(hdc, X, Y);
  232.  
  233. for (int j = 0; j <= T; j++) {
  234. for (int i = 0; i <= T; i++) {
  235. u = 2.0 * M_PI / (double)T * (double)i;
  236. v = 2.0 * W / (double)T * (double)j - W;
  237. Mebius(u, v, R, W, x, y, z);
  238. proj(x, y, z, xx, yy);
  239. X = w * (xx - min_xx) / (max_xx - min_xx);
  240. Y = h * (yy - min_yy) / (max_yy - min_yy);
  241. z_buffer[X][Y] = x;
  242. }
  243. }
  244.  
  245.  
  246. for (int j = 0; j <= T; j++) {
  247. for (int i = 0; i <= T; i++) {
  248. u = 2.0 * M_PI / (double)T * (double)i;
  249. v = 2.0 * W / (double)T * (double)j - W;
  250. Mebius(u, v, R, W, x, y, z);
  251. proj(x, y, z, xx, yy);
  252. X = w * (xx - min_xx) / (max_xx - min_xx);
  253. Y = h * (yy - min_yy) / (max_yy - min_yy);
  254. z_buffer[X][Y] = max(x, z_buffer[X][Y]);
  255. }
  256. }
  257.  
  258. for (int j = 0; j <= v_size; j++) {
  259. for (int i = 0; i <= T; i++) {
  260. u = 2.0 * M_PI / (double)T * (double)i;
  261. v = 2.0 * W / (double)v_size * (double)j - W;
  262. Mebius(u, v, R, W, x, y, z);
  263. proj(x, y, z, xx, yy);
  264. X = w * (xx - min_xx) / (max_xx - min_xx);
  265. Y = h * (yy - min_yy) / (max_yy - min_yy);
  266. if (abs(z_buffer[X][Y] - x) < 0.1) {
  267. if (n_x(R, u, v) + 2.0 * sqrt(2.0) * n_y(R, u, v) + n_z(R, u, v) > 0)
  268. SetPixel(hdc, X, Y, RGB(0, 0, 255));
  269. else
  270. SetPixel(hdc, X, Y, RGB(0, 120, 0));
  271. }
  272. }
  273. }
  274.  
  275. for (int i = 0; i <= u_size; i++) {
  276. for (int j = 0; j <= 2000; j++) {
  277. u = 2.0 * M_PI / (double)u_size * (double)i;
  278. v = 2.0 * W / (double)2000 * (double)j - W;
  279. x = (R + v / 2.0 * cos(u / 2.0)) * cos(u);
  280. y = (R + v / 2.0 * cos(u / 2.0)) * sin(u);
  281. z = v / 2.0 * sin(u / 2.0);
  282. proj(x, y, z, xx, yy);
  283. X = w * (xx - min_xx) / (max_xx - min_xx);
  284. Y = h * (yy - min_yy) / (max_yy - min_yy);
  285. if (abs(z_buffer[X][Y] - x) < 0.1) {
  286. if (n_x(R, u, v) + 2.0 * sqrt(2.0) * n_y(R, u, v) + n_z(R, u, v) > 0)
  287. SetPixel(hdc, X, Y, RGB(0, 0, 255));
  288. else
  289. SetPixel(hdc, X, Y, RGB(0, 120, 0));
  290. }
  291. }
  292. }
  293.  
  294. EndPaint(hWnd, &ps);
  295. break;
  296. case WM_DESTROY:
  297. PostQuitMessage(0);
  298. break;
  299. default:
  300. return DefWindowProc(hWnd, message, wParam, lParam);
  301. }
  302. return 0;
  303. }
  304.  
  305. // Обработчик сообщений для окна "О программе".
  306. INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  307. {
  308. UNREFERENCED_PARAMETER(lParam);
  309. switch (message)
  310. {
  311. case WM_INITDIALOG:
  312. return (INT_PTR)TRUE;
  313.  
  314. case WM_COMMAND:
  315. if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
  316. {
  317. EndDialog(hDlg, LOWORD(wParam));
  318. return (INT_PTR)TRUE;
  319. }
  320. break;
  321. }
  322. return (INT_PTR)FALSE;
  323. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement