计算机图形学-Code 2

版权声明:本文为博主原创文章,欢迎转载,转载请贴上博客地址 http://blog.csdn.net/xdg_blog https://blog.csdn.net/xdg_blog/article/details/52849012
/*------------------------------------
author:XD_G
location:SWUN
time:09/2015~01/2016
course:Computer Graphics
teacher:Tianyun Huang
如果认识黄天云老师,请代我向他问好!
------------------------------------*/
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
#include <vector>
#include <string>
#include <time.h>

using namespace std;

typedef struct  Point {     //点结构
public:
    int x;
    int y;

    struct Point() :x(0), y(0) {}
    struct Point(int  a, int  b) :x(a), y(b) {  }
}Point;

typedef struct Node {   //链表结点
public:
    Point data;
    struct Node *next = NULL;

    struct Node() :data(0, 0), next(NULL) {}
    struct Node(int a, int b) :data(a, b), next(NULL) {}
}Node, *pNode;

//全局变量
static TCHAR szWindowClass[] = _T("win32app");
static TCHAR szTitle[] = _T("Win32  Application");

HINSTANCE hInst;
UINT WIDTH = 800;//窗口宽度
UINT HEIGHT = 600;//窗口高度
COLORREF bkg_clr = RGB(255, 255, 255);//背景色

Node stack;//栈
vector<Point  >  points_set;    //多边形点集

//函数声明
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);//消息处理
void display(HDC hDC);//WM_PAINT消息响应,绘制函数
/*绘图相关*/
void line(HDC hDC, int x_beg, int y_beg, int x_end, int y_end, COLORREF color = RGB(255, 255, 255), int line_width=1, int line_style= PS_SOLID);//画线
void ellipse(HDC hDC, int x_left, int y_top, int x_right, int y_bottom, COLORREF color = RGB(255, 255, 255), int line_width = 1, int line_style = PS_SOLID);//椭圆
void rect(HDC hDC, int x_left, int y_top, int x_right, int y_bottom, COLORREF color = RGB(255, 255, 255), int line_width = 1, int line_style = PS_SOLID);//矩形
void polygon(HDC hDC, vector<Point>* set, COLORREF color = RGB(255, 255, 255), int line_width = 1, int line_style = PS_SOLID);//绘制多边形
void polygon_points();//多边形点集生成
/*栈相关*/
void  SetStackEmpty(pNode L);//将栈置空
bool isStackEmpty(pNode L);//判断栈是否空
void StackPush(pNode L, Point e);//入栈
Point StackPop(pNode L);//出栈

/*实现*/
void ScanLineFill(HDC hDC, int x, int y, COLORREF oldcolor, COLORREF newcolor);//扫描填充

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,    LPSTR lpCmdLine,int nCmdShow){
    WNDCLASSEX wcex;//初始化窗口类
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW|CS_OWNDC;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)CreateSolidBrush(bkg_clr);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = szWindowClass;
    wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
    if (!RegisterClassEx(&wcex))    {//注册窗口类
        MessageBox(NULL,_T("Call to RegisterClassEx failed!"),_T("Win32 Application"),NULL);
        return 1;
    }
    hInst = hInstance; 
    HWND hWnd = CreateWindow(szWindowClass, szTitle,WS_OVERLAPPEDWINDOW,200,100,WIDTH, HEIGHT,  NULL,   NULL,   hInstance,  NULL);//创建窗口
    if (!hWnd)  {//如果创建失败
        MessageBox(NULL,_T("Call to CreateWindow failed!"),_T("Win32 Application"),NULL);
        return 1;
    }
    ShowWindow(hWnd,nCmdShow);//显示
    UpdateWindow(hWnd);//在显示前再次更新
    MSG msg;
    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){
    PAINTSTRUCT ps;
    HDC hdc;
    switch (message){
    case WM_PAINT://重绘
        hdc = BeginPaint(hWnd, &ps);
        display(hdc);
        EndPaint(hWnd, &ps);
        ReleaseDC(hWnd,hdc);
        break;
    case WM_CHAR://响应按键
        switch (wParam) {
        case 27:    //Esc
            PostQuitMessage(0);
            break;
        }
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_CLOSE:
        PostQuitMessage(0);
        return 0;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
        break;
    }
    return 0;
}

void display(HDC hDC) {
    polygon_points();
    srand((unsigned)time(NULL));

    polygon(hDC, &points_set,RGB(255,0,0),3);
    ellipse(hDC, 50, 50, 200, 150, RGB(0, 255, 0),3);
    rect(hDC, 50, 300, 150, 550, RGB(0, 0, 255), 3);
    for (;;) {
        int rgb_a = rand() % 256;
        int rgb_b = rand() % 256;
        int rgb_c = rand() % 256;
        ScanLineFill(hDC, 100, 75, /*bkg_clr*/GetPixel(hDC, 100, 75), RGB(rgb_a, rgb_b, rgb_c));
        ScanLineFill(hDC, WIDTH / 2 + 10, HEIGHT / 2 + 10,  /*bkg_clr*/GetPixel(hDC, WIDTH / 2 + 10, HEIGHT / 2 + 10), RGB(rgb_b, rgb_c, rgb_a));
        ScanLineFill(hDC, 75, 400,/*bkg_clr*/GetPixel(hDC, 75, 400), RGB(rgb_c, rgb_b, rgb_a));
        if (MessageBox(0,  _T("continue?"), _T("warning"),MB_YESNO | MB_ICONQUESTION) == IDYES)
            continue;
        else
            break;
    }
}

void line(HDC hDC, int x_beg, int y_beg, int x_end, int y_end, COLORREF color,int line_width , int line_style) {
    HPEN pen_old;
    pen_old=(HPEN)SelectObject(hDC, CreatePen(line_style,line_width,color));//选择画笔
    MoveToEx(hDC, x_beg, y_beg, NULL);
    LineTo(hDC, x_end, y_end);
    SelectObject(hDC, pen_old);
}

void ellipse(HDC hDC, int x_left, int y_top, int x_right, int y_bottom, COLORREF color, int line_width, int line_style) {
    HPEN pen_old;
    pen_old = (HPEN)SelectObject(hDC, CreatePen(line_style, line_width, color));//选择画笔
    SelectObject(hDC,GetStockObject(NULL_BRUSH));
    Ellipse(hDC, x_left, y_top, x_right, y_bottom);
    SelectObject(hDC, pen_old);
}

void rect(HDC hDC, int x_left, int y_top, int x_right, int y_bottom, COLORREF color, int line_width, int line_style) {
    HPEN pen_old;
    pen_old = (HPEN)SelectObject(hDC, CreatePen(line_style, line_width, color));//选择画笔
    SelectObject(hDC, GetStockObject(NULL_BRUSH));
    Rectangle( hDC, x_left, y_top, x_right, y_bottom);
    SelectObject(hDC, pen_old);
}

void polygon_points() { 
    Point A(20+WIDTH/2, 150+HEIGHT/2);
    Point B(100 + WIDTH / 2, -130 + HEIGHT / 2);
    Point C(-20 + WIDTH / 2, 15 + HEIGHT / 2);
    Point D(-120 + WIDTH / 2, -55 + HEIGHT / 2);
    Point E(-20 + WIDTH / 2, 100 + HEIGHT / 2);
    Point F(-80 + WIDTH / 2, 80 + HEIGHT / 2);
    points_set.push_back(A);
    points_set.push_back(B);
    points_set.push_back(C);
    points_set.push_back(D);
    points_set.push_back(E);
    points_set.push_back(F);
}

void polygon(HDC hDC,vector<Point>* set, COLORREF color, int line_width, int line_style) {
    for (auto pr = set->begin()+1; pr != set->end(); ++pr) {
        auto pl = pr - 1;
        line(hDC, pl->x, pl->y, pr->x, pr->y, color,line_width);
    }
    line(hDC, (set->end()-1)->x, (set->end()-1)->y, set->begin()->x, set->begin()->y, color, line_width);
}

void  SetStackEmpty(pNode L) {      //将栈置空
    L->next = NULL;
}

bool isStackEmpty(pNode L) {    //判是否栈空
    if (L->next == NULL)
        return TRUE;
    else
        return FALSE;
}

void StackPush(pNode L, Point e) {      //入栈
    pNode temp = new Node;
    pNode pt = L;
    while (pt->next)
        pt = pt->next;
    temp->data.x = e.x;
    temp->data.y = e.y;
    pt->next = temp;
}

Point StackPop(pNode L) {       //出栈
    Point temp;
    pNode pt = L;
    while (pt->next)
        pt = pt->next;
    temp.x = pt->data.x;
    temp.y = pt->data.y;
    pt = L;
    while(pt->next->next)
        pt = pt->next;
    pt->next = NULL;
    return temp;
}

void ScanLineFill(HDC hDC,int x, int y, COLORREF oldcolor, COLORREF newcolor) {
    int xl, xr, i;
    bool scanNeedFill;
    Point pt;
    SetStackEmpty(&stack);
    pt.x = x;
    pt.y = y;
    StackPush(&stack, pt);

    while (!isStackEmpty(&stack)) {
        pt = StackPop(&stack);
        y = pt.y;
        x = pt.x;
        while (GetPixel(hDC, x, y) == oldcolor) {   //向右填充
            SetPixel(hDC, x, y, newcolor);
            x++;
        }
        xr = x - 1;

        x = pt.x - 1;
        while (GetPixel(hDC, x, y) == oldcolor) {   //向左填充
            SetPixel(hDC, x, y, newcolor);
            x--;
        }
        xl = x + 1;

        //处理上面一条扫描线
        x = xl;
        y = y + 1;
        while (x < xr) {
            scanNeedFill = FALSE;
            while (GetPixel(hDC, x, y) == oldcolor) {
                scanNeedFill = TRUE;
                x++;
            }

            if (scanNeedFill) {
                pt.x = x - 1;
                pt.y = y;
                StackPush(&stack, pt);
                scanNeedFill = FALSE;
            }
            while (GetPixel(hDC, x, y) != oldcolor&&x < xr)
                x++;
        }

        //处理下面一条扫描线
        x = xl;
        y = y - 2;
        while (x < xr) {
            scanNeedFill = FALSE;
            while (GetPixel(hDC, x, y) == oldcolor) {
                scanNeedFill = TRUE;
                x++;
            }

            if (scanNeedFill) {
                pt.x = x - 1;
                pt.y = y;
                StackPush(&stack, pt);
                scanNeedFill = FALSE;
            }
            while (GetPixel(hDC, x, y) != oldcolor&&x < xr)
                x++;
        }
    }
}
  

猜你喜欢

转载自blog.csdn.net/xdg_blog/article/details/52849012