ゆれるゆれる
#include <windows.h>
#include <math.h>
#define APP_NAME "単振動"
#define R_SIZE 20
#define MSEC 50
#define WIDTH 500
#define HEIGHT 150
#define PI acos(-1)
LRESULT CALLBACK WindowProc(
HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam
) {
HDC hdc;
PAINTSTRUCT ps;
int x, y = HEIGHT/2;
TCHAR str[64];
static double t = 0.0;
const double omg = 5;
const double a0 = 30;
const double v0 = -200;
int A;
double th;
switch (umsg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_CREATE:
SetTimer(hwnd, 1, MSEC, NULL);
return 0;
case WM_TIMER:
t += (double)MSEC / 1000;
th = (v0 == 0) ? 90 : atan(a0*omg/v0);
A = sqrt(pow(a0,2.0)+pow(v0/omg, 2.0));
x = WIDTH/2 - A * sin(omg*t + th);
InvalidateRect(hwnd, NULL, TRUE);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
wsprintf(str, "振幅 %d", A);
TextOut(hdc, 10, 10, str, lstrlen(str));
Ellipse(hdc, x-R_SIZE, y-R_SIZE, x, y);
EndPaint(hwnd, &ps);
return 0;
}
return DefWindowProc(hwnd, umsg, wparam, lparam);
}
int WINAPI WinMain(
HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow
){
MSG msg;
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = APP_NAME;
if(!RegisterClass(&wc)) return 0;
if(CreateWindow(
APP_NAME, TEXT("単振動サンプル"),
(WS_OVERLAPPEDWINDOW ^ WS_THICKFRAME ^ WS_MAXIMIZEBOX) | WS_VISIBLE,
150 , 150 , WIDTH , HEIGHT ,
NULL, NULL, hInstance, NULL
) == NULL) return 0;
while(GetMessage(&msg, NULL, 0, 0) > 0){
DispatchMessage(&msg);
}
return msg.wParam;
}
単振動の式は
x(t) = Asin(ωt + φ)
で表されますが、φの部分はどこからくるのかな~と考えておりまして。
運動方程式を立てると
ma = -kx
になりますね。つまり
x'' = -k/m * x
という二階の常微分方程式になるわけです。
初期条件を考えるときに
t = 0で
x(t) = a
v(t) = b
とか決めるとφがでるっぽいです(正しいのか?)
多分あってるとおもう、違ってたら誰か教えてくださいお願いします