#define _USE_MATH_DEFINES
#include <Windows.h>
#include <wchar.h>
#include <math.h>
#define APP_NAME TEXT("BallisticCurve")
#define dt 0.1
#define g 9.80665 // 標準重力加速度(m/s^2)
// 関数プロトタイプ宣言
void Trace(LPCTSTR format, ...);
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void OnPaint(HWND hWnd);
//==============================================================================
int CALLBACK 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)GetStockObject(BLACK_BRUSH);
wcx.lpszClassName = APP_NAME;
if (RegisterClassEx(&wcx) == 0) {
return 0;
}
// ウィンドウの作成
DWORD dwStyle = WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX;
RECT rc;
SetRect(&rc, 0, 0, 640, 400);
AdjustWindowRect(&rc, dwStyle, FALSE);
HWND hWnd = CreateWindow(
APP_NAME, APP_NAME,
dwStyle,
CW_USEDEFAULT, 0,
rc.right - rc.left, rc.bottom - rc.top,
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;
va_start(arg_ptr, format);
TCHAR buffer[256];
int size = _vsnwprintf_s(buffer, _TRUNCATE, format, arg_ptr);
va_end(arg_ptr);
OutputDebugString(buffer);
if (size < 0) {
OutputDebugString(L"...\n");
}
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg) {
case WM_PAINT:
OnPaint(hWnd);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
void OnPaint(HWND hWnd)
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
Trace(L"OnPaint(%d, %d, %d, %d)\n", ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom);
SelectObject(hdc, GetStockObject(WHITE_PEN));
for (int deg = 15; deg <= 75; deg += 15) {
double v = 40.0; // m/s
double a = deg * M_PI / 180;
double x = 0.0; // m
double y = 1.0; // m
MoveToEx(hdc, int(x * 4), 400 - int(y * 4), NULL);
for (double t = 0; t < 10.0; t += dt) {
double vx = v * cos(a);
double vy = v * sin(a) - g * dt;
a = atan2(vy, vx);
v = sqrt(vx * vx + vy * vy);
v -= 0.002 * v * v * dt; // 空気抵抗
x += vx * dt;
y += vy * dt;
// Trace(L"t=%.1f x=%.1f y=%.1f v=%.1f a=%.1f\n", t, x, y, v, a * 180 / M_PI);
LineTo(hdc, int(x * 4), 400 - int(y * 4));
if (y <= 0.0) break;
}
}
EndPaint(hWnd, &ps);
}