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;
}
 

效果图:

C++ GDI绘图思考题1 足球场的绘制