实验一 绘制任意斜率的直线段 | 使用VS2017工具
这世界上有很多坑,注定有些坑是要填的。下面我就用VS2017使用MFC对这个课堂实验进行填坑。
一、实验目的
(1)掌握任意斜率直线段的重点 Bresenham 扫描转换算法;
(2)掌握 Cline 直线类的设计方法;
(3)掌握状态栏编程方法。
二、实验步骤
打开Visual Studio2017,文件->新建->项目,VC++/MFC/MFC应用程序,弹出设置框选择单文档,点击完成。


首先说一下目录结构,让大家对此有个清晰的了解:
初始项目类结构 项目最后的类结构

在添加函数和变量时,有两种规范的方式:
①使用类视图的类向导,点击CLine类,右键菜单,类向导,这个方式一次性可添加CLine类的所有函数和变量。

②点击CLine类,右键菜单:添加->添加函数/添加变量,这个方式虽然要多次添加,但是可以添加注释。

步骤一:新建CLine类:

代码如下:
CLine类
#pragma once
class CLine
{
public:
CLine();
virtual ~CLine();
private:
// 直线斜率
double m_k;
// 直线系数
double m_b;
//直线起点
CPoint m_start;
//直线终点
CPoint m_end; public:
// 隐函数F(x,y)=y-kx-b,计算误差项
double getDistance(double x,double y);
// 调用CDC对象的MoveTo(),移动到起点
void moveTo(CDC *&pDC);
// 使用直线扫描算法绘制直线
void lineTo(CDC *&pDC);
// 设置直线起点
void setStartPoint(CPoint point);
// 设置直线终点
void setEndPoint(CPoint point);
// 绘制直线斜率在0<k<1范围
void kOne(CDC *&pDC);
// 绘制直线斜率在k>1范围
void kTwo(CDC *&pDC);
// 绘制直线斜率在-1<k<0范围
void kThree(CDC *&pDC);
// 绘制直线斜率在k<-1范围
void kFour(CDC *&pDC);
};
Line.h
CLine类的方法的具体实现( 使用Bresenham 扫描转换算法)。
#include "stdafx.h"
#include "CLine.h" CLine::CLine()
{
} CLine::~CLine()
{
} // 隐函数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) == || (m_end.y - m_start.y) == ||
(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 ( < m_k && m_k < )
kOne(pDC);
else if (m_k > )
kTwo(pDC);
else if (- < m_k && m_k < )
kThree(pDC);
else if (m_k < -)
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 = ;
COLORREF color = RGB(, , ); //设置直线的颜色
CPoint next = m_start; //记录起始点
pDC->SetPixelV(next, color); //绘制起始点
for (int i = m_start.x + ; i <= m_end.x; i++)
{
next.x++; //以X轴为主位移方向
if (d <= ) //直线位于中点误差上方
next.y++; //取上面那个点
pDC->SetPixelV(next, color); //绘制点
d = getDistance((double)next.x + , 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 = ;
COLORREF color = RGB(, , );
CPoint next = m_start;
pDC->SetPixelV(next, color);
for (int i = m_start.y + ; i <= m_end.y; i++)
{
next.y++;
if (d > )
next.x++;
pDC->SetPixelV(next, color);
d = getDistance(next.x + 0.5, (double)next.y + );
}
} // 绘制直线斜率在-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 = ;
COLORREF color = RGB(, , );
CPoint next = m_start;
pDC->SetPixelV(next, color);
for (int i = m_start.x - ; i >= m_end.x; i--)
{
next.x--;
if (d < )
next.y++;
pDC->SetPixelV(next, color);
d = getDistance((double)next.x - , 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 = ;
COLORREF color = RGB(, , );
CPoint next = m_start;
pDC->SetPixelV(next, color);
for (int i = m_start.y - ; i >= m_end.y; i--)
{
next.y--;
if (d < )
next.x++;
pDC->SetPixelV(next, color);
d = getDistance(next.x + 0.5, (double)next.y - );
}
}
CLine.cpp
步骤二:MFCApplication1View视图类中用类向导添加消息的处理程序:

①当左键鼠标按钮按下时,记录直线起点位置 void OnLButtonDown(UINT nFlags, CPoint point)
②当左键鼠标按钮松开时,记录直线终点位置并绘制直线 void OnLButtonUp(UINT nFlags, CPoint point)
③当鼠标移动时,在窗口用户区显示鼠标的x坐标和y坐标 void OnMouseMove(UINT nFlags, CPoint point)
④ 添加CLine类为成员变量
添加后,显示如下:

步骤三:CMainFrame类中CMFCStatusBar状态栏控件更改为public成员变量。

步骤四:MFCApplication1View添加类的具体实现是方法。
在MFCApplication1View如图位置添加代码,

代码如下:
//当左键鼠标按钮按下时,记录直线起点位置
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);
} //当鼠标移动时,在窗口用户区显示鼠标的x坐标和y坐标
void CMFCApplication1View::OnMouseMove(UINT nFlags, CPoint point)
{
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(, nFlags, SBPS_NORMAL, sizeX.cx);
pStatus->SetPaneText(, stringX);
pStatus->SetPaneInfo(, nFlags, SBPS_NORMAL, sizeY.cx);
pStatus->SetPaneText(, stringY); }
CView::OnMouseMove(nFlags, point);
CMainFrame类的消息处理程序
最后,点击本地Windows测试器运行程序,等待一段时间,这个坑就被填好了!
三、实验结果
运行后的实验结果如下:
①在空白Pane内可通过点击鼠标左键并移动鼠标松开左键的方式绘制直线
②右下角有显示鼠标的X坐标和Y坐标

图片1-1
实验一 绘制任意斜率的直线段 | 使用VS2017工具的更多相关文章
- [ACM_暴力][ACM_几何] ZOJ 1426 Counting Rectangles (水平竖直线段组成的矩形个数,暴力)
Description We are given a figure consisting of only horizontal and vertical line segments. Our goal ...
- Liang-Barsky直线段裁剪算法
Liang-Barsky直线段裁剪算法 梁友栋与Barsky提出的裁剪算法以直线的参数方程为基础,把判断直线段与窗口边界求交的 二维裁剪问题转化为求解一组不等式,确定直线段参数的一维裁剪问题.设起点为 ...
- [原创]K8_C段旁注查询工具5.0 30款国外主流CMS识别+智能识别未知CMS
8_C段旁注查询工具V5.0 20161214作者:K8拉登哥哥 唯一QQ:396890445平台: Windows + .NET Framework 4.0 简介:K8_C段 提供4种方式查询子域名 ...
- 实验 1:Mininet 源码安装和可视化拓扑工具
实验 1:Mininet 源码安装和可视化拓扑工具 一.实验目的 掌握 Mininet 的源码安装方法和 miniedit 可视化拓扑生成工具. 二.实验任务 使用源码安装 Mininet 的 2.3 ...
- Bresenham画直线,任意斜率
function DrawLineBresenham(x1,y1,x2,y2) %sort by x,sure x1<x2. if x1>x2 tmp=x1; x1=x2; x2=tmp; ...
- 《图形学》实验三:DDA算法画直线
开发环境: VC++6.0,OpenGL 实验内容: 使用DDA算法画直线. 实验结果: 代码: #include <gl/glut.h> #include <math.h> ...
- js调用百度地图接口绘制任意多边形并获取每个点的经纬度等
来自:https://blog.csdn.net/u013239236/article/details/52213977 侵删 <!DOCTYPE html> <html> & ...
- [ActionScript 3.0] AS3 绘制任意三角形任意顶点到对边的高
注:顶点坐标可以点击 package { import flash.display.Shape; import flash.display.Sprite; import flash.events.Mo ...
- 大厂前端工程师教你如何使用css3绘制任意角度扇形+动画
这里只是做下原理解释,原理:使用两个半圆做角度拼接.比如想绘制一个缺口朝右,缺口弧度30度角的扇形 资源网站搜索大全https://55wd.com 那么将由一个旋转65度角的半圆A+一个旋转-65度 ...
随机推荐
- Windows下Pycharm安装Tensorflow:ERROR: Could not find a version that satisfies the requirement tensorflow
今天在Windows下通过Pycharm安装Tensorflow时遇到两个问题: 使用pip安装其实原理都相同,只不过Pycharm是图形化的过程! 1.由于使用国外源总是导致Timeout 解决方法 ...
- BAT脚本批量调用Sql执行文件 (SqlServer 数据库)
@echo off & setlocal EnableDelayedExpansion set num=0set INSTANCE_HOSTNAME= 地址set INSTANCE_PORT= ...
- 自动化测试环境搭建(appium+selenium+python)
一.需要安装的软件(根据你所需要的版本安装即可,不一定必须按照小编的版本来) JDK:1.8.0_171 Python:3.7.1 node.js:10.13.0 android-sdk_r24.4. ...
- eclipse设置打开java文件目录
1. 第一步: 2. 第二步: 3. 第三步: Location:C:/WINDOWS/explorer.exe Arguments:${container_loc}
- 箭头函数与定时器的this指向问题
函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象. 箭头函数本身没有this,this继承上级的this. 定时器中箭头函数的this指向包含定时器的函数,所以定时器中的箭头函数要 ...
- Elasticsearch:运用search_after来进行深度分页
在上一篇文章 "Elasticsearch:运用scroll接口对大量数据实现更好的分页",我们讲述了如何运用scroll接口来对大量数据来进行有效地分页.在那篇文章中,我们讲述了 ...
- 1.安装Loucust
python 3.x 通过pip安装: pip install locustio 如果是以分布式队列运行locust,需要装一种通信队列的库pyzmq :pip install pyzmq 安装成功 ...
- freertos,串口接收数据后如何发送给任务
http://www.stmcu.org.cn/module/forum/thread-610230-1-1.html http://www.stmcu.org.cn/module/forum/thr ...
- Java 注解(Annotations) 详解
注解是元数据 注解是一种装饰器.一个标记(maker),应用于Java的各种结构之上,例如类.方法.字段.用来为这些结构绑定元数据.注解不包含任何业务逻辑. 只由运行时框架或编译器根据注解信息去执行具 ...
- MFC 静态文本框
窗体上操作控件内容,需要句柄,在控件处使用鼠标右键——添加变量. DoDataExchange()函数会自动生成代码,把ID与变量绑定(即DDX_Control(pDX, IDC_TEXT, objT ...