⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 createpenview.cpp

📁 图形绘制算法实现、区域填充算法的实现过程、图形裁减算法的实现等
💻 CPP
字号:
// CreatePenView.cpp : implementation of the CCreatePenView class
//

#include "stdafx.h"
#include "CreatePen.h"

#include "CreatePenDoc.h"
#include "CreatePenView.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


//直线的DDA算法生成

#define ROUND(a) ((int)(a + 0.5))

void LineDDA2(int xa, int ya, int xb, int yb, CDC* pDC)
{
	int dx = xb - xa;
	int dy = yb - ya;
	int Steps, k;
	float xIncrement, yIncrement;
	float x = xa, y = ya ;
	if(abs(dx) > abs(dy))
		Steps = abs(dx);
	else
		Steps = abs(dy);
	xIncrement = dx/(float)Steps;
	yIncrement = dy/(float)Steps;
	pDC->SetPixel(ROUND(x), ROUND(y), RGB(255, 0, 0));
	for(k=0; k<Steps; k++){
		x += xIncrement;
		y += yIncrement;
		Sleep(10);
		pDC->SetPixel(ROUND(x), ROUND(y), RGB(255, 0, 0));
	}
}


//直线的Bresenham生成算法
void LineBres(int xa, int ya, int xb, int yb, CDC* pDC)
{
	int dx = abs(xa - xb), dy = abs(ya - yb);
	int p = 2*dy - dx;
	int twoDy = 2*dy, twoDyDx = 2*(dy - dx);
	int x, y , xEnd;
	if(xa > xb){
		x = xb;
		y = yb;
		xEnd = xa;
	}
	else{
		x = xa;
		y = ya;
		xEnd = xb;
	}
	pDC->SetPixel(x, y, RGB(255, 0, 0));

	while(x < xEnd){
		x++;
		if(p < 0)
			p += twoDy;
		else{
			y++;
			p += twoDyDx;
		}
		Sleep(10);
		pDC->SetPixel(x, y, RGB(255, 0, 0));
	}
}


void CirclePlotPoint(int xCenter, int yCenter, int x, int y, CDC* pDC)
{
	pDC->SetPixel(xCenter + x, yCenter + y, RGB(255, 0, 0));
	pDC->SetPixel(xCenter - x, yCenter + y, RGB(255, 0, 0));
	pDC->SetPixel(xCenter + x, yCenter - y, RGB(255, 0, 0));
	pDC->SetPixel(xCenter - x, yCenter - y, RGB(255, 0, 0));
	pDC->SetPixel(xCenter + y, yCenter + x, RGB(255, 0, 0));
	pDC->SetPixel(xCenter - y, yCenter + x, RGB(255, 0, 0));
	pDC->SetPixel(xCenter + y, yCenter - x, RGB(255, 0, 0));
	pDC->SetPixel(xCenter - y, yCenter - x, RGB(255, 0, 0));
}


//Bresenham生成圆弧的算法
void Bre_Arc(int xCenter, int yCenter, int Radius, CDC* pDC)
{
	int x, y, distance;
	x = 0;
	y = Radius;
	distance = 3 - 2 * Radius;
	while(x < y){
		Sleep(10);
		//CirclePlotPoint(xCenter, yCenter, x, y, pDC);
		pDC->SetPixel(x, y, RGB(255, 0, 0));
		if(distance < 0)
			distance += 4 * x + 6;
		else{
			distance += 4 * (x - y) + 10;
			y = y - 1;
		}
		x = x + 1;
	}
	if( x = y)
		//CirclePlotPoint(xCenter, yCenter, x, y, pDC);
		pDC->SetPixel(x, y, RGB(255, 0, 0));
}


//正负法绘圆弧
void pn_Arc(int xCenter, int yCenter, int radius, CDC* pDC)
{
	int x, y, f;
	x = xCenter;
	y = yCenter + radius;
	f = 0;
	while(y > yCenter){
		Sleep(10);
		//CirclePlotPoint(xCenter, yCenter, x, y, pDC);
		pDC->SetPixel(x, y, RGB(255, 0, 0));
		if(f > 0){
			f = f - 2 * (y - yCenter) + 1;
			y = y - 1;
		}
		else{
			f = f + 2 * (x - xCenter) + 1;
			x = x + 1;
		}
	}
	if(y = yCenter)
		//CirclePlotPoint(xCenter, yCenter, x, y, pDC);
		pDC->SetPixel(x, y, RGB(255, 0, 0));
}

//中点圆算法
void CircleMidpoint(int xCenter, int yCenter, int radius, CDC* pDC)
{
	int x = 0 ;
	int y = radius;
	int p = 1 - radius;   //初始决策参数
	CirclePlotPoint(xCenter, yCenter, x, y, pDC);
	Sleep(10);
	while(x < y){
		x++;
		if(p < 0)
			p += 2 * x + 1;
		else{
			y--;
			p += 2 * (x - y) + 1;
		}
		Sleep(20);
		CirclePlotPoint(xCenter, yCenter, x, y, pDC);
	}
}


void EllispePlotPoints(int xCenter, int yCenter, int x, int y, CDC* pDC)
{
	pDC->SetPixel(xCenter + x, yCenter + y, RGB(255, 0, 0));
	pDC->SetPixel(xCenter - x, yCenter + y, RGB(255, 0, 0));
	pDC->SetPixel(xCenter + x, yCenter - y, RGB(255, 0, 0));
	pDC->SetPixel(xCenter - x, yCenter - y, RGB(255, 0, 0));
}
//中点法绘制椭圆
void EllispeMidPoint(int xCenter, int yCenter, int Rx, int Ry, CDC* pDC)
{
	int Rx2 = Rx * Ry;
	int Ry2 = Ry * Ry;
	int twoRx2 = 2 * Rx2;
	int twoRy2 = 2 * Ry2;
	int p;
	int x = 0;
	int y = Ry;
	int px = 0;
	int py = twoRy2 * y;

	EllispePlotPoints(xCenter, yCenter, x, y, pDC);

	p = ROUND(Ry2 - (Rx2 * Ry) + (0.25 * Rx2));
	while(px < py){
		x++;
		px += twoRy2;
		if(p < 0)
			p += Ry2 + px;
		else{
			y--;
			py -= twoRx2;
			p += Ry2 + px - py;
		}
		EllispePlotPoints(xCenter, yCenter, x, y, pDC);
	}

	p = ROUND(Ry2 * (x + 0.5) * (x + 0.5) + Rx2 * (y - 1) * (y -1) - Rx2 * Ry2);
	while(y > 0){
		y--;
		py -= twoRx2;
		if(p > 0)
			p += Rx2 - py;
		else{
			x++;
			px += twoRy2;
			p += Rx2 - py + px;
		}
		EllispePlotPoints(xCenter, yCenter, x, y, pDC);
	}
}


////////////////////////////梁友栋-BARSKY算法/////////////////////////
int ClipTest(float q, float d, float* t1, float* t2)
{
	float r;
	int retVal = TRUE;
	if(q < 0.0){
		r = d / q;
		if(r > *t2)
			retVal = FALSE;
		else if(r > *t1)
			*t1 = r;
	}
	else{
		if(q > 0.0){
			r = d / q;
			if(r < *t1)
				retVal = FALSE;
			else if(r < *t2)
				*t2 = r;
		}
		else if(d < 0.0)
			retVal = FALSE;
	}
	return (retVal);
}

void ClipLine(POINT winMin, POINT winMax, POINT p1, POINT p2, CDC* pDC)
{
	float t1 = 0.0, t2 = 1.0;
	float dx = p2.x - p1.x , dy;
	if(ClipTest(-dx, p1.x - winMin.x, &t1, &t2))
		if(ClipTest(dx, winMax.x - p1.x, &t1, &t2)){
			dy = p2.y - p1.y;
			if(ClipTest(-dy, p1.y - winMin.y, &t1, &t2))
				if(ClipTest(dy, winMax.y - p1.y, &t1, &t2)){
					if(t2 < 1.0){
						p2.x = p1.x + t2 * dx;
						p2.y = p1.y + t2 * dy;
					}
					if(t1 > 0.0){
						p1.x += t1 * dx;
						p1.y += t1 * dy;
					}
					//pDC->MoveTo(ROUND(p1.x),ROUND(p1.y));
					//pDC->LineTo(ROUND(p2.x), ROUND(p2.y));
					LineDDA2(ROUND(p1.x),ROUND(p1.y), ROUND(p2.x), ROUND(p2.y), pDC);
				}
		}
}
////////////////////////////梁友栋-BARSKY算法/////////////////////////

////////////////////////////边界填充算法//////////////////////////////

void BoundaryFill4(int x, int y, COLORREF fillClr, COLORREF edgeClr, CDC* pDC)
{
	COLORREF currentPixel;
	currentPixel = pDC->GetPixel(x, y);
	if((currentPixel != edgeClr) && (currentPixel != fillClr)){
		pDC->SetPixel(x, y,fillClr);
		Sleep(1);
		BoundaryFill4(x + 1, y, fillClr, edgeClr, pDC);
		BoundaryFill4(x - 1, y, fillClr, edgeClr, pDC);
		BoundaryFill4(x, y + 1, fillClr, edgeClr, pDC);
		BoundaryFill4(x, y - 1, fillClr, edgeClr, pDC);
	}
}
////////////////////////////边界填充算法//////////////////////////////

/////////////////////////////////////////////////////////////////////////////
// CCreatePenView

IMPLEMENT_DYNCREATE(CCreatePenView, CView)

BEGIN_MESSAGE_MAP(CCreatePenView, CView)
	//{{AFX_MSG_MAP(CCreatePenView)
	ON_COMMAND(ID_DDA_LINE, OnDdaLine)
	ON_COMMAND(ID_MIDLLDEPOINT_CIRCLE, OnMidlldepointCircle)
	ON_COMMAND(ID_BRESENHAM_LINE, OnBresenhamLine)
	ON_COMMAND(ID_PN_ARC, OnPnArc)
	ON_COMMAND(ID_BRESENHAM_ARC, OnBresenhamArc)
	ON_COMMAND(ID_MIDPOINTELLIPSE, OnMidpointellipse)
	ON_COMMAND(ID_LIANG_BARSKY, OnLiangBarsky)
	ON_COMMAND(ID_BOUNDARY_FILL, OnBoundaryFill)
	ON_COMMAND(ID_TRANSFORM, OnTransform)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCreatePenView construction/destruction

CCreatePenView::CCreatePenView()
{
	// TODO: add construction code here
	m_ptStart.x = 100;
	m_ptStart.y = 50;
	m_ptEnd.x = 500;
	m_ptEnd.y = 400;

}

CCreatePenView::~CCreatePenView()
{
}

BOOL CCreatePenView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CCreatePenView drawing

void CCreatePenView::OnDraw(CDC* pDC)
{
	CCreatePenDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	
//创建画笔方法1

/*	for(int i=0 ;i<7 ;i++)
	{
		CPen NewPen1(PS_SOLID+i,1,RGB(255,0,0));//(COLORREF)0x000000FF
		CPen *pOldPen=pDC->SelectObject(&NewPen1);
		pDC->MoveTo(10,20*i+10);
		pDC->LineTo(700,20*i+10);
		pDC->SelectObject(pOldPen);	
	}*/

//创建画笔方法2;
/*
	for(int j=0 ;j<7 ;j++)
	{
		CPen NewPen2;
		NewPen2.CreatePen(PS_SOLID,j,(COLORREF)0x00FF0000);//
		CPen *pOldPen1=pDC->SelectObject(&NewPen2);
		pDC->MoveTo(10,160+20*j);
		pDC->LineTo(700,160+j*20);
		pDC->SelectObject(pOldPen1);
	}*/
//创建坐标
	
}

/////////////////////////////////////////////////////////////////////////////
// CCreatePenView printing

BOOL CCreatePenView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CCreatePenView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CCreatePenView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CCreatePenView diagnostics

#ifdef _DEBUG
void CCreatePenView::AssertValid() const
{
	CView::AssertValid();
}

void CCreatePenView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CCreatePenDoc* CCreatePenView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CCreatePenDoc)));
	return (CCreatePenDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CCreatePenView message handlers


//DDA算法生成直线
void CCreatePenView::OnDdaLine() 
{
	CDC* pDC = GetDC();
	LineDDA2(m_ptStart.x, m_ptStart.y, m_ptEnd.x, m_ptEnd.y, pDC);
	ReleaseDC(pDC);
}


//Bresenham算法生成直线
void CCreatePenView::OnBresenhamLine() 
{
	CDC* pDC = GetDC();
	LineBres(m_ptStart.x, m_ptStart.y + 20, m_ptEnd.x, m_ptEnd.y + 20, pDC);
	ReleaseDC(pDC);
	
}

//Bresenham生成圆弧的算法
void CCreatePenView::OnBresenhamArc() 
{
	CDC* pDC = GetDC();
	Bre_Arc(200, 200, 200, pDC);
	ReleaseDC(pDC);
}

//正负法绘圆弧
void CCreatePenView::OnPnArc() 
{
	CDC* pDC = GetDC();
	pn_Arc(200, 200, 200, pDC);
	ReleaseDC(pDC);
}

void CCreatePenView::OnMidlldepointCircle() 
{
	CDC* pDC = GetDC();
	CircleMidpoint(300, 220, 200, pDC);
	ReleaseDC(pDC);
}





void CCreatePenView::OnMidpointellipse() 
{
	CDC* pDC = GetDC();
	EllispeMidPoint(220, 220, 100, 50, pDC);
	ReleaseDC(pDC);
}

void CCreatePenView::OnLiangBarsky() 
{
	CDC* pDC = GetDC();
	
	POINT ptMin, ptMax;
	ptMin.x = 40, ptMin.y = 40;
	ptMax.x = 400, ptMax.y = 150;
	CRect rect(ptMin, ptMax);
	
	pDC->Rectangle(&rect);
	
	POINT p1, p2;
	p1.x = 25, p1.y = 15;
	p2.x = 450, p2.y = 200;
	pDC->MoveTo(p1);
	pDC->LineTo(p2);
	
	ClipLine(ptMin, ptMax, p1, p2, pDC);
	ReleaseDC(pDC);
}

void CCreatePenView::OnBoundaryFill() 
{
	CDC* pDC = GetDC();
	
	POINT pts[5] ={{20, 20}, {20, 80}, {150, 80}, {150, 40}, {120, 20}};
	pDC->Polygon(pts, 5);
	
	BoundaryFill4(40, 40, RGB(255, 123, 0), RGB(0, 0, 0), pDC);
	
	ReleaseDC(pDC);
}


//二维变换
void CCreatePenView::OnTransform() 
{
	POINT pts[4] = {50, 50, 50, 150, 150, 150, 150, 50};
	POINT refPt = {100, 100};   //平移偏移量
	
	CDC* pDC = GetDC();	

	pDC->Polygon(pts, 4);
	m_transMatrix.Scale2(1, 0.5, refPt);
	m_transMatrix.Translate2(refPt.x, refPt.y);
	m_transMatrix.TransformPoints(4, pts);
	pDC->Polygon(pts, 4);
	ReleaseDC(pDC);	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -