開発環境 Microsoft Visual C++ 2010 Express (SP1)
実行環境 Microsoft Windows XP Home Edition (SP3)
プロジェクトの種類 Win32 プロジェクト
プロジェクト名 Fourier
アプリケーションの種類 Windows アプリケーション
追加のオプション 空のプロジェクト
文字セット Unicode

参考

Fourier.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);
}
 
最終更新:2013年02月17日 20:50