码迷,mamicode.com
首页 > 其他好文 > 详细

Computer Graphics - code_2

时间:2015-12-29 19:26:22      阅读:179      评论:0      收藏:0      [点我收藏+]

标签:

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

  

Computer Graphics - code_2

标签:

原文地址:http://www.cnblogs.com/xd-g/p/5086518.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!