贝塞尔曲线WIN32实现,不用WIN32自带的贝塞尔API实现

贝塞尔曲线WIN32实现,不用WIN32自带的贝塞尔API实现

#include 
#include 

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
	static TCHAR	szAppName[] = TEXT("Bezier");
	HWND			hwnd;
	MSG				msg;
	WNDCLASS		wndclass;

	wndclass.style = CS_HREDRAW | CS_VREDRAW;
	wndclass.lpfnWndProc = WndProc;
	wndclass.cbClsExtra = 0;
	wndclass.cbWndExtra = 0;
	wndclass.hInstance = hInstance;
	wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
	wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wndclass.lpszMenuName = NULL;
	wndclass.lpszClassName = szAppName;

	if (!RegisterClass(&wndclass))
	{
		MessageBox(NULL, TEXT("Program requires Windows NT!"), szAppName, MB_ICONERROR);
		return 0;
	}

	hwnd = CreateWindow(szAppName, TEXT("Bezier Splines Demo"),
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT,
		CW_USEDEFAULT, CW_USEDEFAULT,
		NULL, NULL, hInstance, NULL);

	ShowWindow(hwnd, iCmdShow);
	UpdateWindow(hwnd);

	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}


POINT FindPoint(POINT x, POINT y, int t) {
	POINT z;
	z.x = x.x + (1.0 * t / 100) * (1.0 * y.x - 1.0 * x.x);
	z.y = x.y + (1.0 * t / 100) * (1.0 * y.y - 1.0 * x.y);
	return z;
}

void DrawBezier(HDC hdc, POINT apt[])
{
	POINT	aptt[3];
	POINT   bpt[2], z[200];
	//PolyBezier(hdc, apt, 4);
	for (int t = 0; t <= 131; t++) {
		aptt[0] = FindPoint(apt[0], apt[1], t);
		aptt[1] = FindPoint(apt[1], apt[2], t);
		aptt[2] = FindPoint(apt[2], apt[3], t);

		/*MoveToEx(hdc, aptt[0].x, aptt[0].y, NULL);
		LineTo(hdc, aptt[1].x, aptt[1].y);

		MoveToEx(hdc, aptt[1].x, aptt[1].y, NULL);
		LineTo(hdc, aptt[2].x, aptt[2].y);*/

		bpt[0] = FindPoint(aptt[0], aptt[1], t);
		bpt[1] = FindPoint(aptt[1], aptt[2], t);

		z[t] = FindPoint(bpt[0], bpt[1], t);
	}
	for (int i = 0; i <= 99; i++) {
		MoveToEx(hdc, z[i].x, z[i].y, NULL);
		LineTo(hdc, z[1 + i].x, z[1 + i].y);
	}

	MoveToEx(hdc, apt[0].x, apt[0].y, NULL);
	LineTo(hdc, apt[1].x, apt[1].y);

	MoveToEx(hdc, apt[1].x, apt[1].y, NULL);
	LineTo(hdc, apt[2].x, apt[2].y);

	MoveToEx(hdc, apt[2].x, apt[2].y, NULL);
	LineTo(hdc, apt[3].x, apt[3].y);

}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static POINT	apt[4];
	int				cxClient, cyClient;
	HDC				hdc;
	PAINTSTRUCT		ps;

	switch (message)
	{
	case WM_SIZE:
		cxClient = LOWORD(lParam);
		cyClient = HIWORD(lParam);

		apt[0].x = cxClient / 4;
		apt[0].y = cyClient / 2;

		apt[1].x = cxClient / 3;
		apt[1].y = 3 * cyClient / 4;

		apt[2].x = cxClient / 2;
		apt[2].y = 3 * cyClient / 4;

		apt[3].x = 3 * cxClient / 4;
		apt[3].y = cyClient / 2;

		return 0;

	case WM_LBUTTONDOWN:
	case WM_RBUTTONDOWN:
	case WM_MOUSEMOVE:
		if (wParam & MK_LBUTTON || wParam & MK_RBUTTON)
		{
			hdc = GetDC(hwnd);

			SelectObject(hdc, GetStockObject(WHITE_PEN));
			DrawBezier(hdc, apt);

			if (wParam & MK_LBUTTON)
			{
				apt[1].x = LOWORD(lParam);
				apt[1].y = HIWORD(lParam);
			}

			if (wParam & MK_RBUTTON)
			{
				apt[2].x = LOWORD(lParam);
				apt[2].y = HIWORD(lParam);
			}

			SelectObject(hdc, GetStockObject(BLACK_PEN));
			DrawBezier(hdc, apt);

			ReleaseDC(hwnd, hdc);
		}

	case WM_PAINT:
		InvalidateRect(hwnd, NULL, TRUE);
		hdc = BeginPaint(hwnd, &ps);

		DrawBezier(hdc, apt);

		EndPaint(hwnd, &ps);
		return 0;

	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}

	return DefWindowProc(hwnd, message, wParam, lParam);
}

你可能感兴趣的:(WIN32)