您的位置:首页 > 理论基础

计算机图形学-Code 2

2016-10-18 14:59 239 查看
/*------------------------------------
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(
ce95
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++;
}
}
}
  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: