计算机图形学实验一绘制任意斜率的直线段

一、实验目的

(1)掌握任意斜率直线段的重点 Bresenham 扫描转换算法;

(2)掌握 Cline 直线类的设计方法;

(3)掌握状态栏编程方法。

二、实验步骤

(1)创建MFC应用程序

(2)定义CLine类

计算机图形学实验一绘制任意斜率的直线段_第1张图片计算机图形学实验一绘制任意斜率的直线段_第2张图片

 

  1. 添加消息处理的处理程序

计算机图形学实验一绘制任意斜率的直线段_第3张图片

 

三、实验结果

计算机图形学实验一绘制任意斜率的直线段_第4张图片

 

四、实验体会

在本次实验中,通过不断的探索和实践,我学会了如何创建一个MFC应用程序,将理论运用于实践,掌握了直线类的设计方法,学会了如何绘制任意斜率的方法,虽然过程很艰辛,遇到了许多困难,但是最终通过不断的努力将实验完成了,收获良多。

附录:源代码

 

 CLine.cpp
// 隐函数F(x,y)=y-kx-b,计算误差项
double CLine::getDistance(double x, double y)
{
	return y - m_k * x - m_b;
}


// 调用CDC对象的MoveTo(),移动到起点
void CLine::moveTo(CDC *&pDC)
{
	pDC->MoveTo(m_start);
}


// 使用直线扫描算法绘制直线
void CLine::lineTo(CDC *&pDC)
{
	//如果直线为垂线或是平行线或是k=1的直线
	if ((m_end.x - m_start.x) == 0 || (m_end.y - m_start.y) == 0 ||
		(m_end.x - m_start.x) == (m_end.y - m_end.y) ||
		(m_end.x - m_start.x) == -(m_end.y - m_end.y))
		pDC->LineTo(m_end);
	else
	{
		m_k = ((double)(m_end.y - m_start.y)) / (m_end.x - m_start.x);
		m_b = m_start.y - m_k * m_start.x;
		if (0 < m_k && m_k < 1)
			kOne(pDC);
		else if (m_k > 1)
			kTwo(pDC);
		else if (-1 < m_k && m_k < 0)
			kThree(pDC);
		else if (m_k < -1)
			kFour(pDC);
	}
}


// 设置直线起点
void CLine::setStartPoint(CPoint point)
{
	this->m_end = point;
}


// 设置直线终点
void CLine::setEndPoint(CPoint point)
{
	this->m_start = point;
}


// 绘制直线斜率在0 m_end.x)
	{
		CPoint tmp = m_start;
		m_start = m_end;
		m_end = tmp;
	}
	double d = 0;
	COLORREF color = RGB(0, 0, 0);    //设置直线的颜色
	CPoint next = m_start;  //记录起始点
	pDC->SetPixelV(next, color);    //绘制起始点
	for (int i = m_start.x + 1; i <= m_end.x; i++)
	{
		next.x++;    //以X轴为主位移方向
		if (d <= 0)    //直线位于中点误差上方
			next.y++;    //取上面那个点
		pDC->SetPixelV(next, color);    //绘制点
		d = getDistance((double)next.x + 1, next.y + 0.5);    //下一个中点
	}
}


// 绘制直线斜率在k>1范围
void CLine::kTwo(CDC *&pDC)
{
	if (m_start.y > m_end.y)
	{
		CPoint tmp = m_start;
		m_start = m_end;
		m_end = tmp;
	}
	double d = 0;
	COLORREF color = RGB(0, 0, 0);
	CPoint next = m_start;
	pDC->SetPixelV(next, color);
	for (int i = m_start.y + 1; i <= m_end.y; i++)
	{
		next.y++;
		if (d > 0)
			next.x++;
		pDC->SetPixelV(next, color);
		d = getDistance(next.x + 0.5, (double)next.y + 1);
	}
}


// 绘制直线斜率在-1SetPixelV(next, color);
	for (int i = m_start.x - 1; i >= m_end.x; i--)
	{
		next.x--;
		if (d < 0)
			next.y++;
		pDC->SetPixelV(next, color);
		d = getDistance((double)next.x - 1, next.y + 0.5);
	}
}


// 绘制直线斜率在k<-1范围
void CLine::kFour(CDC *&pDC)
{
	if (m_start.y < m_end.y)
	{
		CPoint tmp = m_start;
		m_start = m_end;
		m_end = tmp;
	}
	double d = 0;
	COLORREF color = RGB(0, 0, 0);
	CPoint next = m_start;
	pDC->SetPixelV(next, color);
	for (int i = m_start.y - 1; i >= m_end.y; i--)
	{
		next.y--;
		if (d < 0)
			next.x++;
		pDC->SetPixelV(next, color);
		d = getDistance(next.x + 0.5, (double)next.y - 1);
	}
}
消息处理程序:
鼠标左键按下
鼠标左键松开
鼠标移动时显示坐标:
void CMFCApplication1View::OnLButtonDown(UINT nFlags, CPoint point)
{
	// 鼠标按下记录起点
	this->line.setStartPoint(point);
	CView::OnLButtonDown(nFlags, point);
}


void CMFCApplication1View::OnLButtonUp(UINT nFlags, CPoint point)
{
	// 鼠标松开记录终点
	this->line.setEndPoint(point);
	CDC *pDC = GetDC();
	this->line.moveTo(pDC);
	this->line.lineTo(pDC);
	CView::OnLButtonUp(nFlags, point);
}


void CMFCApplication1View::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	CString stringX, stringY;
	CMainFrame * pFrame = (CMainFrame *)AfxGetMainWnd();
	CMFCStatusBar * pStatus = &pFrame->m_wndStatusBar;
	if (pStatus != NULL)
	{
		//_T是一个宏,作用是让你的程序支持Unicode编码(双字节编码)
		stringX.Format(_T("x=%d"), point.x);
		stringY.Format(_T("y=%d"), point.y);

		CClientDC dc(this);
		CSize sizeX = dc.GetTextExtent(stringX);
		CSize sizeY = dc.GetTextExtent(stringY);
		pStatus->SetPaneInfo(1, nFlags, SBPS_NORMAL, sizeX.cx);
		pStatus->SetPaneText(1, stringX);
		pStatus->SetPaneInfo(2, nFlags, SBPS_NORMAL, sizeY.cx);
		pStatus->SetPaneText(2, stringY);

	}
	CView::OnMouseMove(nFlags, point);
}

 

你可能感兴趣的:(计算机图形学)