11-重心坐标填充算法

参考:https://www.bilibili.com/video/BV1yd4y197mG/

1.重心坐标定义

2.重心坐标与面积关系

3.计算重心坐标(通过大三角形与小三角形面积比求出)

满足公式条件:P点在三角形内部。

4.三角形包围盒

算法设计

完整代码

// 11-重心坐标填充算法
// 参考 https://www.bilibili.com/video/BV1yd4y197mG/

#define UNICODE
#include <Windows.h>
#include <math.h>
#define WINDOW_TEXT L"11-重心坐标填充算法"
#define ROUND(d) int(floor(d)+0.5)  // 四舍五入
#define RGB2RGB(c) RGB(c.red*255,c.green*255,c.blue*255)

struct RGB24   // RGB颜色
{
public:
    RGB24() :red(0), green(0), blue(0) {};
    RGB24(double red, double green, double blue) :red(red), green(green), blue(blue) {};
    friend RGB24 operator + (const RGB24& clr0, const RGB24& clr1)
    {
        return  RGB24(clr0.red + clr1.red, clr0.green + clr1.green, clr0.blue + clr1.blue);
    };
    friend RGB24 operator * (const RGB24& clr, double scalar)
    {
        return  RGB24(clr.red * scalar, clr.green * scalar, clr.blue * scalar);
    }
    friend RGB24 operator * (double scalar, const RGB24& clr)
    {
        return clr * scalar;
    }

public:
    double red;
    double green;
    double blue;
};

struct Point2  // 带颜色二维点
{
    Point2() :x(0), y(0) {}
    Point2(double x, double y) :x(x), y(y) {}
    Point2(double x, double y, RGB24 c) :x(x), y(y), c(c) {}
    double  x;
    double  y;
    RGB24   c;
};


class Triangle  // 填充三角形
{
public:
    Point2  _P0; // 顶点1
    Point2  _P1; // 顶点2
    Point2  _P2; // 顶点3

public:
    Triangle(){};
    Triangle(Point2 p0, Point2 p1, Point2 p2)
    {
        _P0 = p0;
        _P1 = p1;
        _P2 = p2;
    }
    ~Triangle() {};

    void Fill(HDC hdc)
    {
        // 计算包围盒
        int xMin=ROUND(min(min(_P0.x, _P1.x), _P2.x));
        int yMin=ROUND(min(min(_P0.y, _P1.y), _P2.y));
        int xMax=ROUND(max(max(_P0.x, _P1.x), _P2.x));
        int yMax=ROUND(max(max(_P0.y, _P1.y), _P2.y));

        for (int y = yMin; y < yMax; y++)
        {
            for (int x = xMin; x < xMax; x++)
            {
                double area = _P0.x * _P1.y + _P1.x * _P2.y + _P2.x * _P0.y - _P2.x * _P1.y - _P1.x * _P0.y - _P0.x * _P2.y;
                double area0 = x * _P1.y + _P1.x * _P2.y + _P2.x * y - _P2.x * _P1.y - _P1.x * y - x * _P2.y;
                double area1 = _P0.x * y + x * _P2.y + _P2.x * _P0.y - _P2.x * y - x * _P0.y - _P0.x * _P2.y;
                double area2 = _P0.x * _P1.y + _P1.x * y + x * _P0.y - x * _P1.y - _P1.x * _P0.y - _P0.x * y;

                double alpha = area0 / area;
                double beta  = area1 / area;
                double gamma = area2 / area;

                if (alpha >=0&& beta>=0&&gamma>=0)
                {
                    RGB24 crColor = alpha * _P0.c + beta * _P1.c + gamma * _P2.c;

                    SetPixel(hdc,x,y,RGB2RGB(crColor));
                }

            }

        }
    }

};


LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;
    RECT rc;
    switch (uMsg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;

    case WM_PAINT:
    {
        hdc = BeginPaint(hwnd, &ps);
        GetClientRect(hwnd, &rc);

        SetMapMode(hdc, MM_ANISOTROPIC);
        SetWindowExtEx(hdc, rc.right, rc.bottom, NULL);
        SetViewportExtEx(hdc, rc.right, -rc.bottom, NULL);
        SetViewportOrgEx(hdc, rc.right / 2, rc.bottom / 2, NULL);



        Triangle* triange = new Triangle(
            Point2(   0,  150,RGB24(1.0,   0,   0)),
            Point2(-200, -150,RGB24(  0, 1.0,   0)),
            Point2(200,  -150,RGB24(  0,   0, 1.0))
        );

        triange->Fill(hdc);  // 填充三角形

       

        EndPaint(hwnd, &ps);
    }
    return 0;

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

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
    // Register the window class.
    const wchar_t CLASS_NAME[] = L"CAG";
    WNDCLASS wc = { };

    wc.style = CS_HREDRAW | CS_VREDRAW; // 重新绘制整个工作区
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = CLASS_NAME;
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    RegisterClass(&wc);

    HWND hwnd = CreateWindowEx(
        0,                              // Optional window styles.
        CLASS_NAME,                     // Window class
        WINDOW_TEXT,                    // Window text
        WS_OVERLAPPEDWINDOW,            // Window style

        // Size and position
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

        NULL,       // Parent window    
        NULL,       // Menu
        hInstance,  // Instance handle
        NULL        // Additional application data
    );

    if (hwnd == NULL)
    {
        return 0;
    }
    ShowWindow(hwnd, nCmdShow);


    MSG msg = { };
    while (GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值