「C言語/C++/Fourier」の編集履歴(バックアップ)一覧はこちら

C言語/C++/Fourier」(2013/02/17 (日) 20:50:33) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

|開発環境|Microsoft Visual C++ 2010 Express (SP1)| |実行環境|Microsoft Windows XP Home Edition (SP3)| |プロジェクトの種類|Win32 プロジェクト| |プロジェクト名|Fourier| |アプリケーションの種類|Windows アプリケーション| |追加のオプション|空のプロジェクト| |文字セット|Unicode| 参考 -[[フーリエ級数展開>http://www.wa.commufa.jp/~obaqq75/study/dsp/fourierseries.html]] Fourier.cpp #highlight(cpp){{ // Fourier フーリエ級数展開 #define _USE_MATH_DEFINES #include <Windows.h> #include <tchar.h> #include <math.h> #include <vector> using namespace std; #define APP_NAME TEXT("Fourier") #define YMAX 4 // 関数プロトタイプ宣言 void Trace(LPCTSTR format, ...); LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void OnSize(HWND hWnd, WPARAM wParam, LPARAM lParam); void OnPaint(HWND hWnd); void DrawLine(HDC hdc, RECT rc, vector<double> &f, COLORREF color); // 外部変数 vector<double> fs; // f(t) source vector<double> fd; // f(t) destination //============================================================================== int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) { // ウィンドウクラスの登録 WNDCLASSEX wcx; ZeroMemory(&wcx, sizeof wcx); wcx.cbSize = sizeof wcx; wcx.style = CS_HREDRAW | CS_VREDRAW; wcx.lpfnWndProc = WndProc; wcx.hInstance = hInstance; wcx.hCursor = LoadCursor(NULL, IDC_ARROW); wcx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcx.lpszClassName = APP_NAME; if (RegisterClassEx(&wcx) == 0) { return 0; } // ウィンドウの作成 HWND hWnd = CreateWindow( APP_NAME, APP_NAME, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (hWnd == NULL) { return 0; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); // メッセージループ MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } void Trace(LPCTSTR format, ...) { va_list arg_ptr; TCHAR buffer[256]; int size; va_start(arg_ptr, format); size = _vsntprintf_s(buffer, _countof(buffer), _TRUNCATE, format, arg_ptr); va_end(arg_ptr); OutputDebugString(buffer); if (size < 0) { OutputDebugString(_T("...\n")); } } LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_PAINT: OnPaint(hWnd); return 0; case WM_SIZE: OnSize(hWnd, wParam, lParam); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hWnd, uMsg, wParam, lParam); } void OnSize(HWND hWnd, WPARAM wParam, LPARAM lParam) { WORD width = LOWORD(lParam); WORD height = HIWORD(lParam); Trace(_T("OnSize %u %u %u\n"), wParam, width, height); if (wParam == SIZE_MINIMIZED) return; // f(t) source fs.clear(); for (int x = 0; x <= width; x++) { double t = (2.0 * x / width - 1) * M_PI; // int y = x < width / 2 ? -1 : 1; fs.push_back(t); } // a0 double sum = 0; for (int x = 0; x < width; x++) { sum += fs[x]; } double a0 = sum * (2 * M_PI / width) / (2 * M_PI); Trace(_T("a0=%f\n"), a0); fd.clear(); for (int x = 0; x <= width; x++) { fd.push_back(a0); } // an, bn for (int n = 1; n <= 15; n++) { double an = 0; double bn = 0; for (int x = 0; x < width; x++) { double t = (2.0 * x / width - 1) * M_PI; an += fs[x] * cos(n * t); bn += fs[x] * sin(n * t); } an = an * (2 * M_PI / width) / M_PI; bn = bn * (2 * M_PI / width) / M_PI; Trace(_T("n=%d an=%f bn=%f\n"), n, an, bn); for (int x = 0; x <= width; x++) { double t = (2.0 * x / width - 1) * M_PI; fd[x] += an * cos(n * t) + bn * sin(n * t); } } } void OnPaint(HWND hWnd) { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); RECT rc; GetClientRect(hWnd, &rc); Trace(_T("OnPaint %d %d %d %d\n"), rc.left, rc.top, rc.right, rc.bottom); // 軸 MoveToEx(hdc, 0, rc.bottom / 2, NULL); LineTo(hdc, rc.right, rc.bottom / 2); MoveToEx(hdc, rc.right / 2, 0, NULL); LineTo(hdc, rc.right / 2, rc.bottom); // f(t) DrawLine(hdc, rc, fs, RGB(0,0,255)); DrawLine(hdc, rc, fd, RGB(255,0,0)); EndPaint(hWnd, &ps); } void DrawLine(HDC hdc, RECT rc, vector<double> &f, COLORREF color) { HPEN pen = CreatePen(PS_SOLID, 0, color); HGDIOBJ penOld = SelectObject(hdc, pen); MoveToEx(hdc, 0, int(rc.bottom * (YMAX - f[0]) / (YMAX * 2)), NULL); for (int x = 1; x <= rc.right; x++) { LineTo(hdc, x, int(rc.bottom * (YMAX - f[x]) / (YMAX * 2))); } penOld = SelectObject(hdc, penOld); DeleteObject(pen); } }}

表示オプション

横に並べて表示:
変化行の前後のみ表示: