ゆれるゆれる | spin on the RITZ

ゆれるゆれる

#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


とか決めるとφがでるっぽいです(正しいのか?)



多分あってるとおもう、違ってたら誰か教えてくださいお願いします