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

标签: 计算机图形学  图形学

一、实验目的

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

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

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

二、实验步骤

(1)创建MFC应用程序

(2)定义CLine类

 

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

 

三、实验结果

 

四、实验体会

在本次实验中,通过不断的探索和实践,我学会了如何创建一个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<k<1范围
void CLine::kOne(CDC *&pDC)
{
	//始终保持起点X坐标小于Y坐标
	if (m_start.x > 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);
	}
}


// 绘制直线斜率在-1<k<0范围
void CLine::kThree(CDC *&pDC)
{
	if (m_start.x < m_end.x)
	{
		CPoint temp = m_start;
		m_start = m_end;
		m_end = temp;
	}
	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--;
		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);
}

 

版权声明:本文为weixin_40618723原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_40618723/article/details/105851664

智能推荐

计算机图形学:实验三——直线和圆的描线算法

1. 实验目的 练习直线和圆的光栅扫描线算法。 2. 实验内容和要求 按要求完成以下两个作业。提交纸质实验报告,同时提交实验报告和源代码的电子版。 (I). 利用Bresenham直线扫描算法绘制任意直线段。输入为起点坐标(x0,y0)和终点坐标(x1,y1)以及线宽w,利用Bresenham算法计算离散的近似像素点,并在OpenGL窗口中绘制该线段。要求绘制至少五条线段,具有不同的斜率,不同的起...

计算机图形学实验——直线,多边形绘制算法(橡皮筋效果)

山东大学计算机图形学实验1.1橡皮筋效果绘制 OpenGL橡皮筋效果实现 橡皮筋效果直线 橡皮筋效果多边形 运行截图 小结 OpenGL橡皮筋效果实现 「实验题目」 设计一个二维卡通交互设计系统,实现直线,多边形绘制算法(橡皮筋效果) 「题目分析」 我们知道两点确定一条直线,对于直线来说,橡皮筋效果无非固定直线的一端,另一端随着鼠标的拖动不断绘制;所以大体思路讨论鼠标点击、拖动和绘制直线和这两个控...

【计算机图形学】实验一 · 绘制金刚石图案

一、实验任务 定义二维坐标系原点位于屏幕中心,x轴水平向右为正,y轴铅直向上为正。 以二维坐标系原点为圆心绘制半径为r的圆,将圆的n等分点使用直线彼此连接形成金刚石图案。 程序运行界面提供“文件”、“绘图”和“帮助”三个弹出菜单项。“文件”菜单提供“退出”子菜单项,用于退出应用程...

计算机图形学 实验一 OpenGL基本绘制

文章目录 实验1.1的配置 理论背景 着色器与OpenGL 着色器的编译 绘制简单图形的代码解析 实验 1.2 实验 1.2习题 实验一 实验一 最终成品展示: 包括了实验1.1 1.2和实验一以及对应代码的解析 实验1.1的配置 配置详细见配置环境的文件,我这里顺便上传一下好了 最终能绘制出下图的三角形即可( 不排除有人会第一次配置好了情况结果后面还是出问题的情况比如说我 ) 理论背景 Open...

计算机图形学学习笔记(6.1):直线段裁剪

屏幕映射的概念 如下图所示,要将实体显示在2D的屏幕上,需要先将实体在规范化的观察空间中进行投影变换,然后进行裁剪。这个过程就叫屏幕映射。   裁剪要处理的问题,就是将在观察窗口内部的图形裁剪出来,进行显示。在观察窗口之外的图形,将不被显示。如下图:   首先需要解决的是直线段裁剪问题。下面介绍两个非常著名的算法。 直线段裁剪 Cohen-Sutherland方法 要解决的问题...

猜你喜欢

Mybatis源码的下载,搭建以及阅读源码的姿势

源码下载 mybatis的源码是在github上开源的,所以直接从github上搜索下载即可。 如上图,第一个就是mybatis3的源码项目,下面几个也是项目中常用的依赖项目,分页插件pagehelper,SSM项目需要引入的依赖mybatis-spring,mybatis-plus项目等。 当前最新版本是v3.5.5,可以选择合适的版本下载。我本地选择的是v3.5.4版本,小版本之间没有太大差异...

spring cloud + redis RedisTemplate Api搭建简单Demo

简介 Redis是一种NoSQL数据库,即非关系型数据库。redis是一个key-value存储系统。它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,r...

c++在windows、linux下获取指定文件夹下所有文件名的方法

一般来说,获取指定文件夹下的所有文件名,用python是较为方便的,直接: import os files_name = os.listdir(“一个路径”) 但也有c++程序偶尔也有这个需求,下面就直接上c++在windows和linux去读取文件夹下文件名的方法,不同的系统代码上有一些差别 Windows(vs) vs的环境,主要是用到了头文件<io.h>,...

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

一、实验目的 (1)掌握任意斜率直线段的重点 Bresenham 扫描转换算法; (2)掌握 Cline 直线类的设计方法; (3)掌握状态栏编程方法。 二、实验步骤 (1)创建MFC应用程序 (2)定义CLine类   添加消息处理的处理程序   三、实验结果   四、实验体会 在本次实验中,通过不断的探索和实践,我学会了如何创建一个MFC应用程序,将理论运用于实践...

CSS盒模型

盒子模型 盒子模型是什么 CSS盒子模型就是在CSS技术所使用的一种思维模型。CSS假定所有的HTML文档元素都生成一个描述该元素在HTML文档布局中所占空间的矩形元素框,可以形象地将其看作是一个盒子。通过定义一系列与盒子相关的属性,可极大地丰富和促进各个盒子乃至整个HTML文档的表现效果和布局结构。CSS盒子模型由内容区、填充、边框和空白边四部分组成。内容区是盒子模型的中心,呈现盒子的主要信息内...