C++ GDI绘图思考题1 足球场的绘制
感想:箭头的绘制还是存在缺陷,不太会画圆,只能用椭圆勉强代替
#include <windows.h>
#include <tchar.h>
#include <cmath>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //窗口函数说明
//入口函数代码
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wcex;
HWND hWnd;
MSG msg;
char szWindowClass[] = "窗口示例"; //窗口类名
char szTitle[] = "My Windows"; //窗口标题名
//初始化窗口类
wcex.cbSize = sizeof(WNDCLASSEX); //窗口类的大小
wcex.style = 0; //窗口类型为默认类型
wcex.lpfnWndProc = WndProc; //窗口处理函数为WndProc
wcex.cbClsExtra = 0; //窗口类无扩展
wcex.cbWndExtra = 0; //窗口实例无扩展
wcex.hInstance = hInstance; //当前实例句柄
wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION); //窗口的图标为默认图标
wcex.hCursor = LoadCursor(NULL, IDC_ARROW); //窗口采用箭头光标
wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //窗口背景颜色
wcex.lpszMenuName = NULL; //窗口中无菜单
wcex.lpszClassName = szWindowClass; //窗口类名为 szWindowClass
wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION); //窗口的小图标为默认图标
//窗口类的注册
if(!RegisterClassEx(&wcex))
{
MessageBox(NULL, ("窗口类注册失败!"), ("窗口注册"), NULL);
return 1;
}
//创建窗口
hWnd = CreateWindow(
szWindowClass, //窗口类名
szTitle, //窗口实例的标题名
WS_OVERLAPPEDWINDOW, //窗口的风格
CW_USEDEFAULT, CW_USEDEFAULT, //窗口左上角坐标为默认值
CW_USEDEFAULT, CW_USEDEFAULT, //窗口的高和宽为默认值
NULL, //此窗口无父窗口
NULL, //此窗口无主菜单
hInstance, //创建此窗口应用程序的当前句柄
NULL //不使用该值
);
if(!hWnd) //如果创建窗口失败则发出警告
{
MessageBox(NULL, "创建窗口失败!", ("创建窗口"), NULL);
return 1;
}
ShowWindow(hWnd, nCmdShow); //显示窗口
UpdateWindow(hWnd); //绘制用户区
while(GetMessage(&msg, NULL, 0, 0)) //消息循环
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam; //程序终止时将信息返回系统
}
//窗口函数代码
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
HPEN hpen;
PAINTSTRUCT ps;
RECT rect;
POINT pt;
HBRUSH hbrush;
GetClientRect(hWnd, &rect);
int i;
switch(message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
hpen = CreatePen(PS_SOLID, 1, RGB(255,255,255));
hbrush = CreateSolidBrush(RGB(0,139,69));
SelectObject(hdc, hbrush);
Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
DeleteObject(hbrush);
SelectObject(hdc, hpen);
Rectangle(hdc, rect.right / 30, rect.bottom / 30, rect.right - rect.right / 30, rect.bottom - rect.bottom / 30);
//四个小圆弧
Arc(hdc, rect.right / 30 - rect.right / 60, rect.bottom / 30 - rect.bottom / 60, rect.right / 30 + rect.right / 60, rect.bottom / 30 + rect.bottom / 60, rect.right / 30, rect.bottom / 20, rect.right / 20, rect.bottom / 30);
Arc(hdc, rect.right - rect.right / 20, rect.bottom - rect.bottom / 20, rect.right - rect.right / 60, rect.bottom - rect.bottom / 60, rect.right - rect.right / 30, rect.bottom - rect.bottom / 20, rect.right - rect.right / 20, rect.bottom - rect.bottom / 30);
Arc(hdc, rect.right - rect.right / 20, rect.bottom / 30 - rect.bottom / 60, rect.right - rect.right / 60, rect.bottom / 30 + rect.bottom / 60, rect.right - rect.right / 20, rect.bottom / 30, rect.right - rect.right / 30, rect.bottom / 30 + rect.bottom / 60);
Arc(hdc, rect.right / 30 - rect.right / 60, rect.bottom - rect.bottom / 20, rect.right / 30 + rect.right / 60, rect.bottom - rect.bottom / 60, rect.right / 30 + rect.right / 60, rect.bottom - rect.bottom / 30, rect.right / 30, rect.bottom - rect.bottom / 20);
//中场线
Ellipse(hdc, rect.right / 2 - rect.right / 20, rect.bottom / 2 - rect.bottom / 20, rect.right / 2 + rect.right / 20, rect.bottom / 2 + rect.bottom / 20);
MoveToEx(hdc, rect.right / 2, rect.bottom / 30, &pt);
LineTo(hdc, rect.right / 2, rect.bottom - rect.bottom / 30);
//小小长方形
hpen = CreatePen(PS_SOLID, 3, RGB(255,255,255));
SelectObject(hdc, hpen);
MoveToEx(hdc, rect.right / 30, rect.bottom / 2 + rect.bottom / 20, &pt);
LineTo(hdc, rect.right / 30, rect.bottom / 2 - rect.bottom / 20);
MoveToEx(hdc, rect.right - rect.right / 30, rect.bottom / 2 - rect.bottom / 20, &pt);
LineTo(hdc, rect.right - rect.right / 30, rect.bottom / 2 + rect.bottom / 20);
hpen = CreatePen(PS_SOLID, 1, RGB(255,255,255));
SelectObject(hdc, hpen);
//大长方形
Rectangle(hdc, rect.right / 30, rect.bottom / 2 - rect.bottom / 4, rect.right / 30 + rect.right / 10, rect.bottom / 2 + rect.bottom / 4);
Rectangle(hdc, rect.right - rect.right / 30 - rect.right / 10, rect.bottom / 2 - rect.bottom / 4, rect.right - rect.right / 30, rect.bottom / 2 + rect.bottom / 4);
//小长方形
Rectangle(hdc, rect.right / 30, rect.bottom / 2 - rect.bottom / 10, rect.right / 30 + rect.right / 30, rect.bottom / 2 + rect.bottom / 10);
Rectangle(hdc, rect.right - rect.right / 15, rect.bottom / 2 - rect.bottom / 10, rect.right - rect.right / 30, rect.bottom / 2 + rect.bottom / 10);
//两段小圆弧
Arc(hdc, rect.right / 15 * 2 - rect.right / 70, rect.bottom / 2 - rect.bottom / 15, rect.right / 15 * 2 + rect.right / 70, rect.bottom / 2 + rect.bottom / 15, rect.right / 15 * 2, rect.bottom / 2 + rect.bottom / 15, rect.right / 15 * 2, rect.bottom / 2 - rect.bottom / 15);
Arc(hdc, rect.right - rect.right / 15 * 2 - rect.right / 70, rect.bottom / 2 - rect.bottom / 15, rect.right - rect.right / 15 * 2 + rect.right / 70, rect.bottom / 2 + rect.bottom / 15, rect.right - rect.right / 15 * 2, rect.bottom / 2 - rect.bottom / 15, rect.right - rect.right / 15 * 2, rect.bottom / 2 + rect.bottom / 15);
//三个小点
hbrush = CreateSolidBrush(RGB(255,255,255));
SelectObject(hdc, hbrush);
Ellipse(hdc, rect.right / 30 + rect.right / 30 + rect.right / 240 * 7, rect.bottom / 2 - rect.bottom / 100, rect.right / 30 + rect.right / 30 + rect.right / 30 + rect.right / 240, rect.bottom / 2 + rect.bottom / 100);
Ellipse(hdc, rect.right - rect.right / 15 - rect.right / 30 - rect.right / 240, rect.bottom / 2 - rect.bottom / 100, rect.right - rect.right / 15 - rect.right / 240 * 7, rect.bottom / 2 + rect.bottom / 100);
Ellipse(hdc, rect.right / 2 - rect.right / 240, rect.bottom / 2 - rect.bottom / 100, rect.right / 2 + rect.right / 240, rect.bottom / 2 + rect.bottom / 100);
for(i = 1; i <= 50; i++)
{
double x = (double)(rand() % 100 / 100.0) * rect.right;
double y = (double)(rand() % 100 / 100.0) * rect.bottom;
double x2 = (double)(rand() % 100 / 100.0) * rect.right;
double y2 = (double)(rand() % 100 / 100.0) * rect.bottom;
if(x < rect.right / 15 * 2 || x > rect.right - rect.right / 30 - rect.right / 10 || y < rect.bottom / 30 || y > rect.bottom - rect.bottom / 30 || x2 < rect.right / 30 || x2 > rect.right - rect.right / 30 || y2 < rect.bottom / 30 || y2 > rect.bottom - rect.bottom / 30
|| (x == x2 && y == y2))
{
i--;
continue;
}
double x3, y3;
if(y2 > y && x2 < x)
{
x3 = x2 + rect.right / 100;
y3 = y2 - rect.bottom / 50;
}
else if(y2 < y && x2 > x)
{
x3 = x2 - rect.right / 100;
y3 = y2 + rect.bottom / 50;
}
else if(y2 > y && x2 > x)
{
x3 = x2 - rect.right / 100;
y3 = y2 - rect.bottom / 50;
}
else if(y2 < y && x2 < x)
{
x3 = x2 + rect.right / 100;
y3 = y2 + rect.bottom / 50;
}
else if(y2 == y && x2 < x)
{
x3 = x2 + rect.right / 100;
y3 = y2 + rect.bottom / 50;
}
else if(y2 == y && x2 > x)
{
x3 = x2 - rect.right / 100;
y3 = y2 - rect.bottom / 50;
}
else if(x2 == x && y2 > y)
{
x3 = x2 + rect.right / 100;
y3 = y2 - rect.bottom / 50;
}
else if(x2 == x && y2 < y)
{
x3 = x2 - rect.right / 100;
y3 = y2 + rect.bottom / 50;
}
double x4 = (y3 - y - (y - y2) * x / (x2 - x) - x3 * (x2 - x) / (y - y2)) / ( (y2 - y) / (x2 - x) - (x2 - x) / (y - y2));
double y4 = (y2 - y) / (x2 - x) * (x4 - x) + y;
double x5 = abs(2 * x4 - x3);
double y5 = abs(2 * y4 - y3);
if(x3 < rect.right / 30 || x3 > rect.right - rect.right / 30 || y3 < rect.bottom / 30 || y3 > rect.bottom - rect.bottom / 30 ||
x5 < rect.right / 30 || x5 > rect.right - rect.right / 30 || y5 < rect.bottom / 30 || y5 > rect.bottom - rect.bottom / 30)
{
continue;
}
//随机点
hbrush = CreateSolidBrush(RGB(0,0,255));
SelectObject(hdc, hbrush);
Ellipse(hdc, x, y, x + rect.right / 80, y + rect.bottom / 50);
DeleteObject(hbrush);
//绿箭头
hpen = CreatePen(PS_SOLID, 2, RGB(0,238,0));
SelectObject(hdc, hpen);
MoveToEx(hdc, x, y, &pt);
LineTo(hdc, x2, y2);
POINT lp[3] = {x3, y3, x2, y2, x5, y5};
Polyline(hdc, lp, 3);
DeleteObject(hpen);
//棕色箭头
if(i > 25 && i < 40)
{
hpen = CreatePen(PS_SOLID, 3, RGB(210,180,140));
SelectObject(hdc, hpen);
MoveToEx(hdc, x, y, &pt);
LineTo(hdc, x2, y2);
Polyline(hdc, lp, 3);
DeleteObject(hpen);
}
//橙色箭头
if(i > 45)
{
hpen = CreatePen(PS_SOLID, 3, RGB(255,153,18));
SelectObject(hdc, hpen);
MoveToEx(hdc, x, y, &pt);
LineTo(hdc, x2, y2);
Polyline(hdc, lp, 3);
DeleteObject(hpen);
}
}
DeleteObject(hbrush);
EndPaint(hWnd, &ps);
break;
case WM_SIZE:
InvalidateRect(hWnd, NULL, true);
break;
case WM_DESTROY:
PostQuitMessage(0); //调用POSTQuitMessage发出WM_QUIT消息
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam); //默认时采用系统消息默认处理函数
break;
}
return 0;
}
效果图: