计算机图形学用VC++画直线
计算机图形学实验二:直线的生成算法的实现
实验二: 直线的生成算法的实现班级 08信计2班学号 20080502055 姓名分数一、实验目的和要求:1.理解直线生成的原理;2.掌握几种常用的直线生成算法;3.利用C实现直线生成的DDA算法。
二、实验内容:1.了解直线的生成原理2、掌握几种基本的直线生成算法: DDA画线法、中点画线法、Bresenham画线法。
3、仿照教材关于直线生成的DDA算法, 编译程序。
4.调试、编译、运行程序。
三、实验过程及结果分析1.直线DDA算法:算法原理:已知过端点P0(x0,y0), P1(x1,y1)的直线段L(P0,P1), 斜率为k=(y1-y0)/(x1-x0), 画线过程从x的左端点x0开始, 向x右端点步进, 步长为1个像素, 计算相应的y坐标为y=kx+B。
计算y i+1 = kx i+B=kx i +B+kx=y i +kx当x=1,yi+1=yi+k, 即当x每递增1, y递增k。
由计算过程可知, y与k可能为浮点数, 需要取y整数, 源程序中round(y)=(int)(y+0.5)表示y四舍五入所得的整数值。
(1)程序代码:#include"stdio.h"#include"graphics.h"void linedda(int x0,int y0,int x1,int y1,int color){int x,dy,dx,y;float m;dx=x1-x0;dy=y1-y0;m=dy/dx;y=y0;for(x=x0;x<=x1;x++){putpixel(x,(int)(y+0.5),color);y+=m;setbkcolor(7);}}main(){int a,b,c,d,e;int graphdriver=DETECT;int graphmode=0;initgraph(&graphdriver,&graphmode,"");a=100;b=100;c=200;d=300;e=5;linedda(a,b,c,d,e);getch();closegraph();}运行结果:2.中点画线算法:假定所画直线的斜率为k∈[0,1], 如果在x方向上增量为1, 则y方向上的增量只能在0~1之间。
Visual C++基础入门教程-第10课:绘制直线
学会了画点,下一步就该是画线了,线是由点组成的,每个点的位置用两个数来表示(x,y),即平面直角坐标系,一条直线有两个点,或者说两点确定一条直线,一个是起点,一个是终点,如果连续画线,上一次的终点就是下一次的起点,弄明白了这两个点,我们就来来学习一下,怎样在自己的窗口中画出漂亮的线条来;画线也用到设备,画线的函数是LineTo(hdc,(x,y));其中的(x,y)是终点,起点用上次的终点,第一次起点是(0,0),屏幕的左上角,另一个是移动函数MoveToEx(hdc,(x,y),NULL);把起点设为上一次的终点,下面我们来编制程序:1、启动VC,新建一个名为Line的Win32 Application工程,再新建一个相同名称的头文件和源程序文件,在头文件中输入函数的申明,在源程序中输入窗口框架代码;2、画线的鼠标指针是十字形的,把第3课中的指针文件curMouse拷贝到Line文件夹中,在头文件中加入一句标识符申明#define IDC_MYCUR 201再用记事本新建一个相同文件名的资源文件Line.rc输入鼠标指针的定义:IDC_MYCUR CURSOR DISCARDABLE "curMouse.cur" 保存并关闭文件;3、使用工程菜单中的“添加工程”命令将资源文件Line.rc加入到工程中,再在InitApplication函数中修改加载鼠标指针一句为wcexLine.hCursor=LoadCursor(hInstance,MAKEINTRESOURCE(201));其中wcexLine是窗口类名,根据自己的代码修改一致,注意标识符前后一致;4、加入消息处理函数过程,画线是用鼠标,因此需要处理鼠标按键消息WM_LBUTTONDOWN以及鼠标拖动的消息WM_MOUSEMOVE,还有鼠标抬起WM_LBUTTONUP消息;消息处理过程MainWndProc(绿色双斜杠部分是注释),有的一行太长会自动折到下一行,代码如下,细细品味每一行的作用是铺垫呢,还是操作;是给谁铺垫,操作结果又是什么呢?LRESULT APIENTRY MainWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam){HDC hdc;static HPEN hpenBlue;//申明一支彩色笔;static POINT pointBegin,pointEnd,point;//保存起点和终点,当前点;static int x1,y1;//单击鼠标画线的终点位置switch (message){case WM_CREATE: // 创建一支彩色笔hpenBlue = CreatePen(PS_SOLID, 1, RGB(0,0,255));break;case WM_LBUTTONDOWN://左键按下pointBegin.x =LOWORD(lParam);//初始化起点xpointBegin.y=HIWORD(lParam);//初始化起点ypointEnd.x=LOWORD(lParam);//初始化终点xpointEnd.y=HIWORD(lParam);//初始化终点y//当前点的位置用默认为屏幕左上角(0,0)SetCapture(hWnd);//一直跟着鼠标break;case WM_MOUSEMOVE://进入鼠标移动消息;if(wParam & MK_LBUTTON)//检测左键是否按下;{//进入鼠标拖动;point.x =LOWORD(lParam);//当前鼠标的位置x;point.y=HIWORD(lParam);//当前鼠标的位置y;hdc=GetDC(hWnd);SetROP2(hdc,R2_NOT);//使用与背景色相反的颜色;//第二次用与背景色相反的颜色绘制,可以擦去原来的线条(双重否定);MoveToEx(hdc,pointBegin.x,pointBegin.y,NULL);//画线起点是单击左键时的鼠标的位置LineTo(hdc,pointEnd.x,pointEnd.y);//擦除上次绘出的直线;//第二次移动时,先把第一次的线擦除,然后下面画这次移动的线;MoveToEx(hdc,pointBegin.x,pointBegin.y,NULL);//原来鼠标的位置LineTo(hdc,point.x,point.y);//point是当前鼠标的位置//这两条语句将绘制一条从起点到当前鼠标位置的线;pointEnd.x=point.x; pointEnd.y=point.y;//这两条语句保存当前鼠标位置,以便于鼠标移动后可以擦除这次绘制的直线ReleaseDC(hWnd,hdc);}break;case WM_LBUTTONUP://如果是单击画图将会用彩色笔ReleaseCapture();//解除鼠标跟踪hdc=GetDC(hWnd);SelectObject(hdc, hpenBlue);//换上彩色笔MoveToEx(hdc,point.x,point.y,NULL);//设定起点,在鼠标移动消息中修改了pointx1=LOWORD(lParam);//画线终点x;y1=HIWORD(lParam);//画线终点y;LineTo(hdc,x1,y1);//从起点到当前点画线//point.x=x1;//修改当前点的位置为这次的结束位置,//point.y=y1;//不修改就一直用同一个起点(星形)ReleaseDC(hWnd,hdc);break;case WM_DESTROY://退出应用程序;PostQuitMessage(0);//向系统发送一条WM_QUIT消息,break;default: //让系统帮着处理的消息return (DefWindowProc(hWnd,message,wParam,lParam)); }return 0;}保存一下文件,单击编译条上的“构建”按钮,如果出现错误就仔细检查一下,然后单击“执行”按钮,看看又前进一步的程序窗口;本节学习了在用户区用鼠标画线的代码设计,如果你成功地完成了练习,请继续学习下一课内容;。
计算机图形学-三种直线生成算法及圆的生成算法
计算机科学与技术学院2013-2014学年第一学期《计算机图形学》实验报告班级:110341C学号:110341328姓名:田野教师:惠康华成绩:实验(一):平面图形直线和圆的生成一、实验目的与要求1.在掌握直线和圆的理论基础上,分析和掌握DDA生成直线算法、中点生成直线算法、Bresenham生成直线算法、中点画圆算法、Bresenham圆生成算法。
2.熟悉VC6.0MFC环境,利用C语言编程实现直线和圆的生成。
3.比较直线生成三种算法的异同,明确其优点和不足。
同时了解圆的生成算法适用范围。
二、实验内容1.掌握VC6.0环境中类向导和消息映射函数的概念,并且为本次实验做好编程准备工作。
2. 用C语言进行编程实现上述算法,并且调试顺利通过。
3. 在MFC图形界面中显示不同算法下的图形,并且注意对临界值、特殊值的检验。
完成后保存相关图形。
三、算法分析➢DDA直线生成算法描述:1)给定一直线起始点(x0,y0)和终点(x1,y1)。
分别计算dx=x1-x0,dy=y1-y0。
2)计算直线的斜率k=dy/dx。
当|k|<1时转向3);当|k|<=1时,转向4);3)当x每次增加1时,y增加k。
即(xi,yi)→(xi+1,yi+k)。
直到xi增加到x1。
并且每次把得到的坐标值利用系统函数扫描显示出来。
但要注意对y坐标要进行int(y+0.5)取整运算。
结束。
4)对y每次增加1时,x增加1/k,即(xi,yi)→(xi+1/k,yi+1)。
直到yi增加到y1. 并且每次把得到的坐标值利用系统函数扫描显示出来。
但要注意对x坐标要进行int(x+0.5)取整运算。
结束。
➢中点生成算法描述:算法基本思想:取当前点(xp,yp),那么直线下一点的可能取值只能近的正右方点P1(xp+1,yp)或者P2(xp+1,yp+1)。
为了确定好下一点,引入了这两点中的中点M(xp+1,yp+0.5)。
这时可以把改点带入所在直线方程,可以观察该中点与直线的位置关系。
基于vc的线条类设计
摘要本文主要介绍了一个简单的绘图软件的详细设计方法和过程。
它是我们大学生毕业前的一次考验。
它能实现一个简单的用户界面,并能实现几个基本的图元的移动,删除和改变颜色。
它的设计方法是利用MAC工程中的GDI(Graphics Device Interface)类库函数来实现画图的。
该软件的基本功能包括基本图形绘制,更改图元绘制条件(改变图元颜色),删除图元等。
要求:实现所见即所得绘图功能;实现图元的插入功能;实现图形文件的存储功能。
该软件是基于MAC实现的,在文本框的基础上实现绘图功能。
能通过程序设计以达到提高VC++的编程水平的目的。
随着社会的不断进步,人们对图形的要求越来越高,因此我们有必要掌握好图形的绘制,虽然本软件知识一个十分简单的软件。
但我们应该不断的学习,以便将来更好的适应发展。
关键词:MFC,图元,文本框AbstractThis paper describes a simple method of mapping software and process the detailed design. It is a test for students before graduation. It can implement a simple user interface, and can achieve a few basic primitive move, delete and change color. Its design is to use MAC Project GDI (Graphics Device Interface) function to implement drawing libraryThe software's basic functions, including basic graphics rendering, change primitive plan condition (change line color). Request: Realizes sees namely the obtained cartography function; Realizes primitive insertion; Realizes the graphic file memory function. The software is based on the MAC implementation.In the text box based on the graphics. Can the programming achieve enhances VC++ the programming level goal.As society progresses, people become increasingly demanding on the graphics, and we need to master the drawing, although the software knowledge a very simple software. But we should keep learning in order to better adapt to future development.Keyword: MFC, primitive, text box目录1 前言 (1)1.1 课题背景 (1)1.2 Visual C + +简介 (2)1.3 目的和内容 (2)1.4 课题技术关键 (3)2 VC++中MFC介绍 (4)2.1 MFC基本概念 (4)2.1.1 MFC简介 (4)2.1.2 封装 (5)2.1.3 继承 (5)2.1.4 GDI+简介 (6)2.2 MFC部分函数简介 (7)3 程序功能设计 (10)3.1 总体设计 (10)3.1.1流程分析 (10)3.1.2功能框架结构 (11)3.2 程序功能模块 (11)3.2.1绘制图元 (11)3.2.2改变绘制条件 (11)3.2.3文件持久性 (11)4 系统功能实现 (12)4.1 建立MFC工程 (12)4.2 实现按钮映射 (14)4.3 实现消息映射 (18)5 结果分析 (30)5.1 使用方法 (30)5.2 运行结果 (30)5.3 存在的问题 (30)5.4 解决方案 (30)6 结论 (31)致谢 (32)参考文献 (33)1 前言1.1 课题背景计算机图形技术是随着计算机技术在图形处理领域中的应用而发展起来的一门新技术,是伴随着电子计算机及其外围设备的发展而产生的,现已成为计算机应用科学中的一个重要分支,在许多行业中起着越来越大的作用。
计算机图形学实验
实验三MFC画直线最近自己在学习如何在VC 6.0 开发环境下的使用MFC AppWizard(exe)来绘画一条直线,虽然比较简单,通过这样的练习可以帮助你熟悉MFC的开发环境以及其中的消息传递机制,希望对于像我一样初入MFC图形绘制学习的人有帮助第一步:构建MFC窗体打开Visual C++ 6.0编译器新建→工程→MFC AppWizard(exe),工程名以DrawLine为例,然后确定。
为了方便,在MFC应用程序向导—步骤1当中选择“单文档”,其余所有的步骤都为默认值,直接“完成”。
这样一个简单的MFC 窗体就构建好了,自己不妨Compile—Build—BuildExecute一下。
第二步:编辑菜单项选择ResourceView视窗展开Menu文件夹,左键双击IDR_DRAWLITYPE,右边就会出现菜单图形编辑界面,为了简化,我们只在添加帮助→DrawLine功能选择项。
双击空白会弹出“菜单项目属性”对话框。
ID:ID_DRAW_LINE;标明:DrawLine(&D),其它的为缺省。
第三步:建立消息命令如果此时运行该程序,你会发现帮助—DrawLine的功能选项是灰色的,原因就在于我们还没有添加该功能的消息命令相应函数。
通过“查看—Message Maps—Project:DrawLine—Class name:CDrawLineView—Object IDs:ID_DRAW_LINE—选定COMMAND—Add Function…”,其它为默认,最后确定完成。
现在如果再重新运行该程序的话,会发现原来的灰色已经消除了。
第四步:添加鼠标消息响应打开ClassView视窗,右键选定CDrawLineView,选择Add Windows Messsage Handler会弹出对话框,完成CDrawLineView类的WM_LBUTTONDOWN、WM_MOUSEMOVE、WM_LBUTTONUP三个Windows消息事件的新建。
计算机图形学实验--完整版-带结果--vc++实现
计算机图形学实验报告信息学院计算机专业20081060183 周建明综括:利用计算机编程语言绘制图形,主要实现以下内容:(1)、中点算法生成任意斜率直线,并设置线型线宽。
(2)、中点算法生成圆(3)、中点算法生成椭圆(4)、扫描算法实现任意多边形填充(5)、Cohen_Sutherland裁剪(6)、自由曲线与曲面的绘制(7)、二维图形变换(8)、三视图变换实验一、直线的生成一、实验内容根据提供的程序框架,修改部分代码,完成画一条直线的功能(中点画线法或者Bresenham画线法任选一),只要求实现在第一象限内的直线。
二、算法原理介绍双击直线生成.dsw打开给定的程序,或者先启动VC++,文件(file)→打开工作空间(open workspace)。
打开直线生成view.cpp,按注释改写下列函数:1.void CMyView::OnDdaline() (此为DDA生成直线)2.void CMyView::OnBresenhamline()(此为Bresenham画直线)3.void CMYView::OnMidPointLine()(此为中点画线法)三、程序源代码1.DDA生成直线画法程序:float x,y,dx,dy,k;dx=(float)(xb-xa);dy=(float)(yb-ya);k=dy/dx;x=xa;y=ya;if(abs(k)<1){for (x=xa;x<=xb;x++){pdc->SetPixel(x, int(y+0.5),COLOR);y=y+k;}}if(abs(k)>=1){for(y=ya;y<=yb;y++){pdc->SetPixel(int(x+0.5),y,COLOR);x=x+1/k;}}//DDA画直线结束}2.Bresenham画直线源程序:float b,d,xi,yi;int i;float k;k=(yb-ya)/(xb-xa);b=(ya*xb-yb*xa)/(xb-xa);if(k>0&&k<=1)for(i=0;i<abs(xb-xa);i++){ d=ya+0.5-k*(xa+1)-b;if(d>=0){ xi=xa+1;yi=ya;xa++;ya=ya+0.5;}if(d<0){ xi=xa+1;yi=ya+1;xa++;ya=ya+1.5;}pdc->SetPixel(xi,yi,COLOR);}//BresenHam画直线结束}3.中点画线法源程序:float b,d,xi,yi;int i;float k;k=(yb-ya)/(xb-xa);b=(ya*xb-yb*xa)/(xb-xa);if(k>0&&k<=1)for(i=0;i<abs(xb-xa);i++){ d=ya+0.5-k*(xa+1)-b;if(d>=0){ xi=xa+1;yi=ya;xa++;ya=ya+0.5;}if(d<0){ xi=xa+1;yi=ya+1;xa++;ya=ya+1.5;}pdc->SetPixel(xi,yi,COLOR); }//BresenHam画直线结束}四、实验结果1、DDA生成直线2、Bresenham画直线3、中点画线法实验二、bresenham画圆一、实验内容根据提供的程序框架,修改部分代码,用Bresenham画法画一段圆弧或者画圆。
C语言之图形学算法
C语言之图形学算法图形学算法是计算机图形学领域中的重要内容,它涉及到图形的创建、显示和处理等方面。
在C语言中,有一些常用的图形学算法可以帮助我们实现各种各样的图形效果。
本文将介绍一些常见的C语言图形学算法,包括直线绘制算法、圆绘制算法和多边形填充算法等。
一、直线绘制算法直线是图形学中最基础的图形之一,其绘制算法也是最简单的。
在C语言中,常用的直线绘制算法有DDA算法和Bresenham算法。
1. DDA算法DDA(Digital Differential Analyzer)算法是一种直线绘制算法,其基本思想是通过计算直线的斜率和每个像素点之间的差值来实现直线的绘制。
下面是DDA算法的伪代码:```dx = x2 - x1dy = y2 - y1step = max(abs(dx), abs(dy))x_increment = dx / stepy_increment = dy / stepx = x1y = y1plot(x, y)for i in range(step):x = x + x_incrementy = y + y_incrementplot(round(x), round(y))```2. Bresenham算法Bresenham算法是一种更加高效的直线绘制算法,它通过利用整数运算和误差累积的方式来实现直线的绘制。
下面是Bresenham算法的伪代码:```dx = abs(x2 - x1)dy = abs(y2 - y1)if dx > dy:step = dxelse:step = dyx_increment = dx / stepy_increment = dy / stepy = y1plot(x, y)for i in range(step):if dx > dy:x = x + x_incrementelse:y = y + y_incrementplot(round(x), round(y))```二、圆绘制算法圆是一种常见的图形,在计算机图形学中,圆的绘制算法也是一个重要的问题。
计算机图形学 使用VC开发绘图程序的基本方法
七、思考题(尽量做,计入成绩) :
1、为什么要用 CDC 定义一个对象来作图? Windows 使用与设备无关的图形设备环境进行显示 。MFC 基础类库定义了设备环境对象类----CDC 类。 因为使用的是 mfc,如果是 sdk 的话就得用 dc,这个 cdc 想当是一个给设备画画的笔。 2、如果要绘制多条直线,应该如何编程?
4、 VC 中编程环境中,工程(project)是什么意义?为什么要用 project 的方式管理代码?
Project 文件的扩展名是 dsp,这个文件中存放的是一个特定的工程,也就是特定的应用程序的有关信息, 每个工程都对应有一个 dsp 类型的文件。 clw 为扩展名的文件是用来存放应用程序中用到的类和资源的信 以 息的,这些信息是 VC 中的 ClassWizard 工具管理和使用类的信息来源。 因为用 project 的方式管理代码比较方便,可以看成是在一个文件夹下进行的。
3、 在 MyView.cpp 文件的 OnDraw 函数中加入如下代码。 pDC->MoveTo(100,100); pDC->LineTo(200,200); CPen *pOldPen; CPen dashPen; dashPen.CreatePen(PS_DASH,1,RGB(255,0,0)); pOldPen = pDC->SelectObject(&dashPen); pDC->LineTo(300,100); pDC->SelectObject(pOldPen); pDC->LineTo(400,200);
实验(No. 1
)题目:使用 VC 开发绘图程序的基本方法
实验目的及要求:
一、实验目的:
编写一个具有一定功能的 MFC 类库应用程序 (引入简单的视图/文档概念) 掌握 GDI 画图的基本方法, , 并调用系统函数画直线。
计算机图形学实验一:画直线
贵州大学实验报告学院:计算机科学与技术专业:计算机科学与技术班级:计科131如果 d<0,则M在理想直线下方,选右上方P1点;如果 d=0,则M在理想直线上,选P1/ P2点。
由于d是xi和yi的线性函数,可采用增量计算提高运算效率。
1.如由pi点确定在是正右方P2点(d>0).,则新的中点M仅在x方向加1,新的d值为:d new=F(xi+2,yi+0.5)=a(xi+2)+b(yi+0.5)+c而 d old=F(xi+1,yi+0.5)=a(xi+1)+b(yi+0.5)+cd new=d old+a= d old-dy2.如由pi点确定是右上方P1点(d<0),则新的中点M在x和y方向都增加1,新的d值为d new=F(xi+2,yi+1.5)=a(xi+2)+b(yi+1.5)+c而 d old=F(xi+1,yi+0.5)=a(xi+1)+b(yi+0.5)+cd new=d old+a+b= d old-dy+dx在每一步中,根据前一次第二迭中计算出的d值的符号,在正右方和右上方的两个点中进行选择。
d的初始值: d0=F(x0+1,y0+0.5)=F(x0,y0)+a+b/2=a+b/2=-dy+dx/2 F(x0,y0)=0,(x0,y0)在直线上。
为了消除d的分数,重新定义 F(x,y)=2(ax+by+c)则每一步需要计算的d new 是简单的整数加法dy=y1-y0,dx=x1-x0d0=-2dy+dxd new=d old-2*dy,当 d old>=0d new=d old-2(dy-dx),当d old<0Bresenham画线算法算法原理:与DDA算法相似,Bresenham画线算法也要在每列象素中找到与理想直线最逼近的象素点。
根据直线的斜率来确定变量在x或y方向递增一个单位。
另一个方向y或x实验内容#include"stdafx.h"#include<glut.h>#include<iostream>#include<cmath>#include<stdio.h>using namespace std;void init(){glClearColor(1.0, 1.0, 1.0, 1.0);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0, 200.0, 0.0, 150.0);}void IntegerBresenhamline(){int x1 = 10, y1 = 10, x2 = 150, y2 = 100;int dx = abs(x2 - x1);int dy = abs(y2 - y1);int x, y;int e = -dx;if (x1 > x2){x = x2;y = y2;x2 = x1;}else{x = x1;y = y1;}glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0, 0.0, 0.0);glBegin(GL_LINES);glVertex2i(x, y);while (x < x2){if (e >= 0){y++;e = e - 2 * dx;}glVertex2i(x, y);x++; e += 2 * dy;}glEnd();glFlush();}void MidPointLine(){int x, y, x1 = 10, y1 = 10, x2 = 150, y2 = 100;int dy = y1 - y2;int dx = x2 - x1;int d = 2 * dy + dx;int dx1 = 2 * dy;int dx2 = 2 * (dx + dy);if (x1 > x2){x = x2;y = y2;x2 = x1;}else{x = x1;y = y1;}glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0, 0.0, 0.0);glBegin(GL_LINES);glVertex2i(x, y);while (x < x2){if (d<0){y++; x++;d += dx2;}else{x++, d += dx1;}glVertex2i(x, y);}glEnd();glFlush();}int main(int argc, char** argv){glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowPosition(50, 100);glutInitWindowSize(400, 300);int choice;printf("输入你想画的直线 0代表Bresenham 1代表中点画线\n");while (1){scanf("%d", &choice);switch (choice){case 0:glutCreateWindow("Bresenham Draw Line");init();glutDisplayFunc(IntegerBresenhamline);glutMainLoop();break;case 1:glutCreateWindow("middle Point Line");init();glutDisplayFunc(MidPointLine);glFlush();glutMainLoop();break;default:printf("输入有误,请重新输入\n");break;}}return 0;}实验结果实验总结通过这次试验我对于中点生成算法和Bresenham生成算法有了进一步的了解,在平时上课的基础上对计算机图形学有了更深的认识,同时对课程内容也更加了解。
计算机图形学直线段生成绘制的实现算法
计算机图形学直线段⽣成绘制的实现算法实验⼆直线段⽣成绘制的实现算法班级 10信计专接本学号 20100504008 姓名吴晓楠分数⼀、实验⽬的和要求:1.了解计算机图形学的原理、⽅法和应⽤。
2.熟悉直线的⽣成算法,掌握直线的绘制3.实现C语⾔编写图形程序。
学会了解VC++的基本应⽤同时了解TC图形环境配置,学习简单的图形画法,并⽐较画法的优劣,尝试在计算机实现,得到图形,验证⽐较图形。
⼆、实验内容:1、掌握直线段的⽣成算法,并⽤C/WIN-TC/VC++实现算法,包括中点法⽣成直线,微分数值法⽣成直线段等。
2、编程实现DDA算法、Bresenham算法、中点画线法绘制直线段三、实验结果分析1、⽣成直线的DDA算法算法思想:⼀个坐标轴上以单位间隔增量,决定另⼀个坐标轴上最靠近线段路径的对应整数值。
假定x2﹣x1的绝对值⼤于y2﹣y1的绝对值,取x为⼀个象素单位长,即x 每次递增⼀个象素,然后利⽤下式计算相应的y值:yk+1﹦yk﹢△y﹦yk﹢m·△x 对于|m|>1的线段,可通过计算由Y⽅向的增量△y引起的改变来⽣成直线:xk+1﹦xk﹢△x﹦xk﹢m·△y⽣成直线的DDA算法思想是源⽤初中直线的⽅程得出来的,⽽⽣成直线的中点算法是通过将DDA算法的⽅程式改为隐函数形式,然后通过与中点的⽐较确定该取的像素,绘制图线。
/* DDA */#includevoid linedda(int x0,int y0,int x1,int y1,int color){int x,dy,dx,y;float m;dx=x1-x0;dy=y1-y0;m=dy/dx;y=y0;for(x=x0;x<=x1;x++){putpixel(x,(int)(y+0.5),color);y+=m;}}main(){int a,b,c,d,e;int graphdriver=DETECT;int graphmode=0;initgraph(&graphdriver,&graphmode,""); cleardevice();a=0;b=100;c=200;d=300;e=200;linedda(a,b,c,d,e);getch();closegraph();}运⾏结果:VC++环境:#include#include// 四舍五⼊int Round(float x){return (int)(x < 0 ? x - 0.5 : x + 0.5); }// 使⽤ DDA 算法画任意斜率的直线(包括起始点,不包括终⽌点)void Line_DDA(int x1, int y1, int x2, int y2, int color){float x, y; // 当前坐标点float cx, cy; // x、y ⽅向上的增量int steps = abs(x2 - x1) > abs(y2 - y1) ? abs(x2 - x1) : abs(y2 - y1); x = (float)x1;y = (float)y1;cx = (float)(x2 - x1) / steps;cy = (float)(y2 - y1) / steps;for(int i = 0; i < steps; i++){putpixel(Round(x), Round(y), color); // 在坐标 (x, y) 处画⼀个 color 颜⾊的点x += cx;y += cy;}}// 主函数void main(){initgraph(640, 480);// 测试画线Line_DDA(100, 100, 100, 478, RED);// 按任意键退出getch();}2、Bresenham直线算法是⽤来描绘由两点所决定的直线的算法,它会算出⼀条线段在 n 维光栅上最接近的点。
计算机图形学实验—中点算法画直线
计算机图形学实验报告班级:软件1102姓名:***学号:************中点算法的线段光栅化一、设计思想和算法流程1.假定直线斜率0<K<1假定直线斜率0<K<1,且已确定点亮象素点P (X p ,Y p ),则下一个与直线最接近的像素只能是P1点或P2点。
设M 为中点,Q 为交点,现需确定下一个点亮的象素。
当M 在Q 的下方-> P 2离直线更近更近->取P 2 。
M 在Q 的上方-> P 1离直线更近更近->取P 1M 与Q 重合, P 1、P 2任取一点。
问题:如何判断M 与Q 点的关系?由常识知:若y=kx+b;F(x,y)=y-kx-b;则有 ()()()⎪⎩⎪⎨⎧<>=点在直线下方0,点在直线上方0,点在直线上面0,y x F y x F y x F假设直线方程为:ax +by +c=0 (y=(-a/b)x-c/b)通过两点不能唯一确定a,b,c,取 a=y 0-y 1, b=x 1-x 0, c=x 0y 1-x 1y 0F(x,y)=ax +by +c=b(y-(-a/b)x-c/b); ()()()⎪⎩⎪⎨⎧<>=点在直线下方0,点在直线上方0,点在直线上面0,y x F y x F y x F则有∴欲判断M 点是在Q 点上方还是在Q 点下方,只需把M 代入F (x ,y ),并检查它的符号。
构造判别式:d=F(M)=F(x p +1,y p +0.5)=a(x p +1)+b(y p +0.5)+c当d<0,M 在直线(Q 点)下方,取右上方P 2;当d>0,M 在直线(Q 点)上方,取右方P 1;当d=0,选P 1或P 2均可,约定取P 1;能否采用增量算法呢?若d ≥0 ---->M 在直线上方->取P1;此时再下一个象素的判别式为 d 1=F(x p +2, y p +0.5)=a(x p +2)+b(y p +0.5)+c= a(x p +1)+b(y p +0.5)+c +a=d+a ;增量为a若d<0 ------>M 在直线下方->取P2;此时再下一个象素的判别式为 d 2= F(x p +2, y p +1.5)=a(x p +2)+b(y p +1.5)+c= a(x p +1)+b(y p +0.5)+c +a +b=d+a+b ;增量为a+b画线从(x0, y0)开始,d的初值d0=F(x0+1, y0+0.5)= a(x0 +1)+b(y0 +0.5)+c= F(x0, y0)+a+0.5b = a+0.5b由于只用d 的符号作判断,为了d来摆脱小数,提高效率。
C#画直线
C#画直线实现实例解析C#画直线的操作有的时候我们会在实际开发遇到这样的需求,那么C#画直线是如何实现的呢?这里我们来看看具体的实现代码,通过代码的介绍希望对你的开发有所帮助。
C#画直线实现实例:1.//以下是完整代码,可以直接编译运行2.//-----C#画直线---------ing System;ing System.Collections.Generic;ing System.Windows.Forms;ing System.Drawing;7.space q29.{10.static class Program11.{12./// ﹤summary﹥13./// 应用程序的主入口点。
14./// ﹤/summary﹥15.[STAThread]16.static void Main()17.{18.Application.EnableVisualStyles();19.Application.SetCompatibleTextRenderingDefault(false);20.Application.Run(new Form1());21.}22.}23.24./// ﹤summary﹥25./// 线条对象26./// ﹤/summary﹥27.class Line28.{29./// ﹤summary﹥30./// 建立线条对象,并设置起点31./// ﹤/summary﹥32./// ﹤param name="startPoint"﹥此线条的起点﹤/param﹥33.public Line(Point startPoint)34.{35.StartPoint = startPoint;36.EndPoint = startPoint;37.}38.public Point StartPoint = Point.Empty;39.public Point EndPoint = Point.Empty;40.}41.42.public class DrawPanel : Control43.{44.public DrawPanel()45.{46.this.DoubleBuffered = true;47.this.SetStyle(48.ControlStyles.OptimizedDoubleBuffer |49.ControlStyles.ResizeRedraw, true);50.}51.}52.53./// ﹤summary﹥54./// C#画直线之窗口定义55./// ﹤/summary﹥56.public class Form1 : Form57.{58.public Form1()59.{60.drawPanel.BackColor = Color.White;61.drawPanel.Cursor = Cursors.Cross;62.drawPanel.Dock = DockStyle.Fill;63.drawPanel.MouseDown +=64.new MouseEventHandler(drawPanel_MouseDown);65.drawPanel.MouseUp +=66.new MouseEventHandler(drawPanel_MouseUp);67.drawPanel.MouseMove +=68.new MouseEventHandler(drawPanel_MouseMove);69.drawPanel.Paint +=70.new PaintEventHandler(drawPanel_Paint);71.Controls.Add(drawPanel);72.}73.74./// ﹤summary﹥75./// C#画直线之用于保存绘出线条的集合76./// ﹤/summary﹥77.private List﹤Line﹥ lines = new List﹤Line﹥();78.79./// ﹤summary﹥80./// 用于保存当前正在绘制的线条81./// ﹤/summary﹥82.private Line drawingLine = null;83.84./// ﹤summary﹥85./// 用于显示绘图的面板组件86./// ﹤/summary﹥87.private DrawPanel drawPanel = new DrawPanel();88.89./// ﹤summary﹥90./// 在绘图区释放鼠标,结束当前线条绘制91./// ﹤/summary﹥92./// ﹤param name="sender"﹥﹤/param﹥93./// ﹤param name="e"﹥﹤/param﹥94.void drawPanel_MouseUp(object sender, MouseEventArgs e)95.{96.if (drawingLine == null) return;97.drawingLine.EndPoint = e.Location;98.drawingLine = null;99.}100.101./// ﹤summary﹥102./// 在绘图区按下鼠标,开始绘制新线条103./// ﹤/summary﹥104./// ﹤param name="sender"﹥﹤/param﹥105./// ﹤param name="e"﹥﹤/param﹥106.void drawPanel_MouseDown(object sender, MouseEventArgs e) 107.{108.drawingLine = new Line(e.Location);109.lines.Add(drawingLine);110.}111.///C#画直线112./// ﹤summary﹥113./// 在绘图区移动鼠标时,如果正在绘制新线条,就更新绘制面板114./// ﹤/summary﹥115./// ﹤param name="sender"﹥﹤/param﹥116./// ﹤param name="e"﹥﹤/param﹥117.void drawPanel_MouseMove(object sender, MouseEventArgs e) 118.{119.if(drawingLine != null)120.{121.drawingLine.EndPoint = e.Location;122.drawPanel.Invalidate();123.}124.}125.126./// ﹤summary﹥127./// 绘制效果到面板128./// ﹤/summary﹥129./// ﹤param name="sender"﹥﹤/param﹥130./// ﹤param name="e"﹥﹤/param﹥131.void drawPanel_Paint(object sender, PaintEventArgs e) 132.{133.Bitmap bp = new Bitmap(134.drawPanel.Width, drawPanel.Height); // 用于缓冲输出的位图对象135.Graphics g = Graphics.FromImage(bp);136.137.g.SmoothingMode =138.System.Drawing.Drawing2D.139.SmoothingMode.AntiAlias; // 消锯齿(可选项)140.141.Pen p = new Pen(Color.Black);142.foreach (Line line in lines)143.{144.if (line == drawingLine)145.{146.// 当前绘制的线条是正在鼠标定位的线条147.p.Color = Color.Blue;148.}149.else150.{151.p.Color = Color.Black;152.}153.g.DrawLine(p, line.StartPoint, line.EndPoint); 154.}155.// 将缓冲位图绘制到输出156. e.Graphics.DrawImage(bp, Point.Empty);157.}158.}159.}160.//C#画直线。
利用VC编写简单的绘图程序
利用VC编写简单的绘图程序上机实验环境亦可选择Microsoft Visual C++〔以下简称VC〕。
VC是美国微软公司生产的基于其Windows系统的软件开发工具。
它具有使用灵活,并与32位Windows内核〔使用于Windows 2000/Windows XP〕高度兼容的特点,从而被Windows程序员们广泛使用。
VC 在图形图像处理方面有着广泛的应用,MFC中提供了大量的图形图像函数,下面我们将对使用VC/MFC编写简单的绘图程序。
一、使用VC编写MFC单文档应用程序很简单,只需要按照下面几个步骤进行:1.翻开MSVC集成开发环境。
双击桌面或“开始〞菜单中的Microsoft VisualC++6.0,不久将看到VC的编辑窗口,如图3-5:图1 VC启动界面2.选择菜单“File | New〞,在弹出的对话框中1)单击上方的选项卡“Project〞,2)选择“MFC AppWizard(exe)〞,3)在“Project name〞一栏中填写工程名,例如draw,4)在“Location〞一栏中填写你想把文件存放的位置〔目录〕。
然后按“OK〞。
见图2。
注意:第4〕步中指定你自己的目录,不要使用系统的缺省目录或者随便放在根目录或者其他的目录下。
这样便于你找到自己编写的程序。
图2 应用程序向导主界面3.在MFC Appwizard-Step 1中选择“Single Document〞,即单文档应用程序,点击“Finish〞,如图3所示。
注意:对于下面的操作我们可以忽略,直接点Finish即可。
图3 应用程序向导中选择单文档视图4.系统弹出一个当前工程信息的对话框,如图4所示,直接点“OK〞即可。
图4 新建工程信息5.进入程序编写的主界面,屏幕左下方为工作区,如图5所示,工作区中共有三种视图,分别是:1)文件视图〔“FileView〞〕,主要包括头文件,cpp文件以及资源文件。
我们在头文件中一般添加类的定义,类的成员变量和函数的声明,而在cpp文件中具体实现函数。
计算机图形学-直线的生成算法的实现
实验二 直线的生成算法的实现班级 08信计2班 学号 59 姓名 分数一、实验目的和要求1.理解直线生成的基本原理。
2.掌握几种常用的直线生成算法。
3.利用Visual C++实现直线生成的DDA 算法。
二、实验内容1.了解直线的生成原理,尤其是Bresenham 画线法原理。
2.掌握几种基本的直线生成算法:DDA 画线法、Bresenham 画线法、中点画线法。
3.利用Visual C++实现直线生成的DDA 算法,在屏幕上任意生成一条直线。
三、实验步骤1.直线的生成原理:(1)DDA 画线法也称数值微分法,是一种增量算法。
是一种基于直线的微分方程来生成直线的方法。
(2)中点画线法原理以下均假定所画直线的斜率[0,1]k ∈,如果在x 方向上的增量为1,则y 方向上的增量只能在01之间。
中点画线法的基本原理是:假设在x 坐标为p x 的各像素点中,与直线最近者已经确定为(,)p p P x y ,用小实心圆表示。
那么,下一个与直线最近的像素只能是正右方的1(1,)p p P x y +,或右上方的2(1,1)p p P x y ++,用小空心圆表示。
以M 为1P 和2P 的中点,则M 的坐标为(1,0.5)p p x y ++。
又假设Q 是理想直线与垂直线1p x x =+的交点。
显然,若M 在Q 的下方,则2P 离直线近,应取2P 为下一像素点;若M 在Q 的上方,则1P 离直线近,应取1P 为下一像素点。
(3)B resenham 画线法原理直线的中点Bresenham 算法的原理:每次在主位移方向上走一步,另一个方向上走不走步取决于中点偏差判别式的值。
给定理想直线的起点坐标为P0(x0,y0),终点坐标为P1(x1,y1),则直线的隐函数方程为:0b kx y y)F(x,=--= (3-1)构造中点偏差判别式d 。
b x k y y x F y x F d i i i i M M -+-+=++==)1(5.0)5.0,1(),(⎩⎨⎧≥<+=+)0( )0( 11d y d y y i i i(1) 当d<0时b x k y y x F d i i i i i -+-+=++=+)2(5.1)5.1,2(1k d k b x k y i i i -+=-+-+-+=11)1(5.0⑵ 当d ≥0时b x k y y x F d i i i i i -+-+=++=+)2(5.0)5.0,2(1k d k b x k y i i i -=--+-+=)1(5.02.实现前面所述的各种直线生成算法,包括DDA 算法、中点生成算法、Bresenham 生成算法等。
计算机图形学划线实验报告
计算机图形学划线实验报告《计算机图形学》实验报告实验⼀直线、圆(弧)⽣成算法⼀、实验⽬的及要求1. 了解光栅图形显⽰器的⼯作原理和特点;2. 学习C/VC环境下的基本绘图⽅法;3. 实践与巩固直线的基本⽣成算法。
4. 掌握直线扫描转换算法的原理及实现;5. 学习圆(弧)的基本⽣成算法;6. 实践圆(弧)的基本⽣成算法;7. 掌握圆弧扫描转换算法的原理及实现;⼆、理论基础1、有关直线⽣成算法有DDA(数值微分)、中点画线线算法、Bresenham⽣成算法数值微分法先算出直线的斜率,然后从起点开始,确定最佳逼近于直线的y坐标。
假设起点的坐标为整数。
让x递增1,y相应递增k。
中点划线算法中若直线在x⽅向增加⼀个单位,y的增量只能在0、1之间。
假设当前像素点已经确定,下⼀像素点就只可能有两种情况,将这两点的中点带⼊直线⽅程中,通过中点在直线的上、下⽅来判断下⼀点的坐标。
Bresenham算法是通过各⾏、各列像素中⼼构造⼀组虚拟⽹络格线,按直线从起点到中点的顺序计算直线与各垂直⽹格线的交点,然后确定该列像素中与此交点最近的像素。
2、有关画圆的算法圆的扫描转换(中点画圆法)、Bresenham画圆算法圆的扫描转换算法同中点画线类似,将圆分为8份,先讨论圆的第⼀象限上半部分,从(0,R)点顺时针确定最佳逼近于该圆弧的像素序列。
之后通过对称画出全部圆。
Bresenham画圆算法考虑圆在第⼀象限上的点,每确定⼀像素,则下⼀像素有三种可能,通过判断右下⽅的像素与圆的位置关系再分为三种情况,之后通过这三个点与圆的距离远近确定最佳逼近像素。
三、算法设计与分析1、数值微分法int x0=0,y0=0,x1=800,y1=400; //数值微分法,|k|<=1float dx,dy,k,x,y;dx=x1-x0;dy=y1-y0;k=dy/dx;y=y0;for(x=x0;x<=x1;x++){pDC->SetPixel(x,int(y+0.5),color);y=y+k;}该程序中每⼀步的x、y值是⽤前⼀步的值加上⼀个增量来获得的。
计算机图形学画直线——制作过程
cs.lpszName = _T( "绘制任意直线" );
cs.style = WS_OVERLAPPEDWINDOW;
cs.cx=500;
cs.cy=400;
return TRUE;
修改static UINT indicators[] =
{
int x=-(rt.Width()/2)/10;
int y=(int)(k*x+c+0.5);
float e=k*x+c-y-0.5;
for(int i=0;i<=rt.Width()/10;i++)
{
pDC->Ellipse(rt.Width()/2+x*10-3,rt.Height()/2-y*10-3,rt.Width()/2+x*10+3,rt.Height()/2-y*10+3);
{
pDC->Ellipse(rt.Width()/2+x*10-3,rt.Height()/2-y*10-3,rt.Width()/2+x*10+3,rt.Height()/2-y*10+3);
x++;
e+=k;
if(e<0)
{
y--;
e++;
}
}
}
else if(k>1)//斜率大于1
{
int y=-(rt.Height()/2)/10;
}
pDC->SelectObject(pOldPen);
计算机图形学VC++绘图基础
四、绘制基本图形
7. 其他绘图函数 (2) CRect的构造函数
* 绘制椭圆 BOOL Ellipse( int x1, int y1, int x2, int y2 ); BOOL Ellipse( LPCRECT lpRect ); (3) 画饼图 BOOL pie (int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4); BOOL pie (LPCRECT lpRect, POINT ptStart, POINT ptEnd);
四、绘制基本图形
7. 其他绘图函数 (2) CRect的构造函数 CRect();
CRect( int l, int t, int r, int b ); CRect( POINT topLeft, POINT bottomRight ); * 绘制矩形 void FrameRect( LPCRECT lpRect, CBrush* pBrush ); void FillRect( LPCRECT lpRect, CBrush* pBrush ); Rectangle (int x1, int y1, int x2, int y2); Rectangle (LPCRECT lpRect); * 绘制椭圆 BOOL Ellipse( int x1, int y1, int x2, int y2 ); BOOL Ellipse( LPCRECT lpRect );
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
四、绘制基本图形
5. 设置当前画笔 CPen的构造函数 CPen(); CPen( int nPenStyle, int nWidth, COLORREF color); CPen的CreatePen函数 BOOL CreatePen(int nPenStyle, int nWidth, COLORREF color); 例: CPen *pOld, pen( PS_DOT, 1, RGB( 255, 0, 0)); pOld=pDC->SelectObject(&pen); 绘图 pDC->SelectObject(pOld);
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
for(x=x0;x<=x1;x++)
{
dc.SetPixel(ROUND(x),ROUND(y),rgb);
if(d<0)
{
y++;
d+=1-k;
}
else
d-=k;
}
}
运行结果:
}
}
void CTestView::Mbline(double x0, double y0,double x1,double y1) //直线中点Bresenham函数
{
CClientDC dc(this);
COLORREF rgb=RGB(0,0,255); //定义直线颜色为蓝色
double x,y,d,k;
实验一基本图形生成算法
实验目的:
掌握中点Bresenham绘制直线的原理
设计中点Bresenham算法
编程实现中点Bresenham算法
实验描述:
使用中点Bresenham算法绘制斜率为0≤k≤1的直线。
算法设计:
直线中点Bresenham算法
1.输入直线的起点坐标P0(x0,y0)和终点坐标P1(x1,y1)。
2.定义直线当前点坐标x,y、定义中点偏差判别式d、定义直线斜率k、定义像素点颜色rgb。
3.x=x0,y=y0ቤተ መጻሕፍቲ ባይዱ计算d=0.5-k,k=(y1-y0)/(x1-x0),rgb=RGB(0,0,255)。
4.绘制点(x,y),判断d的符号。若d<0,则(x,y)更新为(x+1,y+1),d更新为d+1-k;否则(x,y)更新为(x+1,y),d更新为d-k。
5.如果当前点x小于x1,重复步骤4,否则结束。
源程序:
1)// TestView.h
#include "InputDlg.h"//对话框头文件
class CTestView : public CView
{
…..
}
2)//TestView.cpp
#define ROUND(a) int(a+0.5)//四舍五入
…..
void CTestView::OnMbline()//菜单响应函数
{
InputDlg dlg;
if(dlg.DoModal()==IDOK)
{
AfxGetMainWnd()->SetWindowText(":直线中点Bresenham算法");
RedrawWindow();
Mbline(dlg.m_x0,dlg.m_y0,dlg.m_x1,dlg.m_y1);