中点画线算法

合集下载

中点画线法

中点画线法
} }
}
void Display(void)
{
glClear(GL_COLOR_BUFFER_BIT); //用当前背景色填充窗口
glColor3f(1.0f, 0.0f, 0.0f); //设置当前的绘图颜色为红色
LineMidPointBre(1,1,1,-5); //调用中点Bresenham算法实现直线的扫描转换
DownIncre=2*dx;
while(y>=y1)
{
glPointSize(3);
glBegin(GL_POINTS);
glVertex2i(x,y);
glEn
{
x++;
{ d=dx-2*dy;
UpIncre=-2*dy;
DownIncre=-2*dx-2*dy;
while(x<=x1)
{
glPointSize(3);
glBegin(GL_POINTS);
glVertex2i(x,y);
glEnd();
glutInitWindowSize(360,360); //设置窗口的尺寸
glutInitWindowPosition(270,270); //设置窗口的位置
glutCreateWindow("中点Bresenham算法绘制任意斜率直线"); //设置标题
glutDisplayFunc(Display); //设置当前窗口的显示回调函数
gluOrtho2D(-10.0,10.0,-10.0,10.0);
}
void LineMidPointBre(GLint x0, GLint y0, GLint x1, GLint y1)

计算机图像图形学-中点画线法

计算机图像图形学-中点画线法

场景渲染
通过中点画线法,游戏开 发者可以快速渲染复杂的 场景,提高游戏运行效率。
计算机辅助设计
机械零件绘图
在计算机辅助设计中,中 点画线法可以用于绘制机 械零件的轮廓和细节,提 高绘图精度。
建筑设计
中点画线法可以用于建筑 设计领域,生成建筑物的 平滑轮廓,提高设计效果。
电路板设计
在电路板设计中,中点画 线法可以用于绘制电路路 径,优化电路布局和信号 传输。
图像处理与编辑
图像平滑处理
中点画线法可以用于图像平滑处 理,减少图像中的噪声和细节失
真。
图像修复
中点画线法可以用于图像修复,对 损坏或缺失的图像部分进行修复和 填充。
图像变换与合成
通过中点画线法,图像处理与编辑 软件可以实现图像的缩放、旋转和 平移等变换操作,以及图像合成和 拼接等操作。
PART 04
优化线条质量可以提高绘制的准确性和视觉效果,使线条 更加平滑、自然。
PART 03
中点画线法的应用场景
REPORTING
WENKU DESIGN
游戏开发
01
02
03
游戏中的பைடு நூலகம்图绘制
中点画线法可以用于游戏 中的地图绘制,生成平滑、 连续的路径,提高游戏体 验。
角色移动动画
在游戏开发中,中点画线 法可以用于生成角色移动 动画,使角色移动更加自 然流畅。
PART 02
中点画线法的实现过程
REPORTING
WENKU DESIGN
确定起点和终点
01
确定线条的起点和终点是中点画 线法的第一步,通常通过输入坐 标或鼠标点击屏幕上的位置来确 定。
02
起点和终点的坐标需要精确,否 则可能导致线条绘制错误或出现 偏差。

《图形学》实验四:中点Bresenham算法画直线

《图形学》实验四:中点Bresenham算法画直线

《图形学》实验四:中点Bresenham算法画直线VC++6.0,OpenGL使⽤中点Bresenham算法画直线。

1//中点Bresenham算法⽣成直线2 #include <gl/glut.h>3 #include <math.h>45#define WIDTH 500 //窗⼝宽度6#define HEIGHT 500 //窗⼝⾼度7#define DRAWLINE1 MidpointBresenham(100,200,200,100); //画直线8#define DRAWLINE2 MidpointBresenham(200,100,450,400); //画直线910#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") //取消控制台1112void Init() //初始化13 {14 glClearColor(1.0f,1.0f,1.0f,1.0f); //设置背景颜⾊,完全不透明15 glColor3f(1.0f,0.0f,0.0f); //设置画笔颜⾊1617 glMatrixMode(GL_PROJECTION); //设置投影18 gluOrtho2D(0.0, WIDTH, 0.0, HEIGHT); //设置投影区域19 }2021void MidpointBresenham(int x0,int y0,int x1,int y1) //中点Bresenham算法画线22 {23int dx,dy,d,UpIncre,DownIncre,x,y;24if(x0>x1){25 x=x1;x1=x0;x0=x;26 y=y1;y1=y0;y0=y;27 }28 x = x0,y = y0;29 dx = x1-x0;30 dy = y1-y0;31if(dy>0&&dy<=dx){ //0<k<=132 d = dx-2*dy;33 UpIncre = 2*dx-2*dy;34 DownIncre = -2*dy;35while(x<=x1){36 glBegin(GL_POINTS);37 glVertex2i(x,y);38 glEnd();39 x++;40if(d<0){41 y++;42 d+=UpIncre;44else45 d+=DownIncre;46 }47 }48else if((dy>=(-dx))&&dy<=0) //-1<=k<=049 {50 d=dx-2*dy;51 UpIncre=-2*dy;52 DownIncre=-2*dx-2*dy;53while(x<=x1)54 {55 glBegin(GL_POINTS);56 glVertex2i(x,y);57 glEnd();58 x++;59if(d>0)60 {61 y--;62 d+=DownIncre;63 }64else d+=UpIncre;65 }66 }67else if(dy<(-dx)) //k<-168 {69 d=-dy-2*dx;70 UpIncre=2*dx+2*dy;71 DownIncre=2*dx;72while(y>=y1)73 {74 glBegin(GL_POINTS);75 glVertex2i(x,y);76 glEnd();77 y--;78if(d<0)79 {80 x++;81 d-=UpIncre;82 }83else d-=DownIncre;84 }85 }8687else//k>1和k不存在88 {89 d=dy-2*dx;90 UpIncre=2*dy-2*dx;91 DownIncre=-2*dx;92while(y<=y1)93 {94 glBegin(GL_POINTS);95 glVertex2i(x,y);96 glEnd();97 y++;98if(d<0)99 {100 x++;101 d+=UpIncre;103else d+=DownIncre;104 }105 }106 }107108void Display() //显⽰函数109 {110 glClear(GL_COLOR_BUFFER_BIT); //清空颜⾊堆栈111112 DRAWLINE1 //画直线113 DRAWLINE2 //画直线114115 glFlush(); //清空缓冲区指令116 }117118int main(int argc,char** argv)119 {120 glutInit(&argc,argv);121 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); //初始化显⽰模式122 glutInitWindowSize(WIDTH,HEIGHT); //设置窗⼝尺⼨123 glutInitWindowPosition(200,100); //设置窗⼝位置124 glutCreateWindow("画直线"); //创建窗⼝125126 glutDisplayFunc(Display); //注册显⽰函数127 Init(); //初始化128 glutMainLoop(); //进⼊程序循环129return0;130 }Freecode :。

直线段的扫描转换算法

直线段的扫描转换算法

直线段的扫描转换算法数值微分(DDA)法设过端点P0(x0 ,y0)、P1(x1 ,y1)的直线段为L(P0 ,P1),那么直线段L的斜率L的起点P的横坐标x0向L的终点P1的横坐标x1步进,取步长=1(个象素),用L的直线方程y=kx+b计算相应的y坐标,并取象素点(x,round(y))作为当前点的坐标。

因为:y= kx i+1+bi+1= k1x i+b+k x= y i+k x因此,当x =1; y i+1 = y i+k。

也确实是说,当x每递增1,y递增k(即直线斜率)。

依照那个原理,咱们能够写出DDA画线算法程序。

DDA画线算法程序void DDALine(int x0,int y0,int x1,int y1,int color){ int x;float dx, dy, y, k;dx = x1-x0; dy=y1-y0;k=dy/dx,;y=y0;for (x=x0;x< x1;x++){ drawpixel (x, int(y+, color);y=y+k;}}注意:咱们那个地址用整型变量color表示象素的颜色和灰度。

举例:用DDA方式扫描转换连接两点P0(0,0)和P1(5,2)的直线段。

x int(y+ y+0 0 01 0 +2 1 +3 1 +4 2 + 图2.1.1 直线段的扫描转换注意:上述分析的算法仅适用于|k| ≤1的情形。

在这种情形下,x每增加1,y最多增加1。

当|k| 1时,必需把x,y地位互换,y每增加1,x相应增加1/k。

在那个算法中,y与k必需用浮点数表示,而且每一步都要对y进行四舍五入后取整,这使得它无益于硬件实现。

中点画线法假定直线斜率k在0~1之间,当前象素点为(x p,y p),那么下一个象素点有两种可选择点P1(x p+1,y p)或P2(x p+1,y p+1)。

假设P1与P2的中点(x p+1,y p+)称为M,Q为理想直线与x=x p+1垂线的交点。

扫描转换算法——DDA、中点画线画圆、椭圆

扫描转换算法——DDA、中点画线画圆、椭圆

扫描转换算法——DDA、中点画线画圆、椭圆我的理解:在光栅图形学中,由于每⼀个点的表⽰都只能是整数值,所以光栅图形学实际只是对对实际图形的近似表⽰。

数值微分法(DDA):以下PPT截图来⾃北京化⼯⼤学李辉⽼师代码实现:import matplotlib.pyplot as pltimport matplotlib.patches as patchesfrom pylab import *def init(ax):#将主标签设置为1的倍数majorLocator = MultipleLocator(1);#设置主刻度标签的位置,标签⽂本的格式ax.xaxis.set_major_locator(majorLocator);ax.yaxis.set_major_locator(majorLocator);ax.grid(True);if__name__ == '__main__':x0, y0, x1, y1 = map(int, input("请输⼊直线的起点与终点: ").split('')) ax = subplot(title='DDA');ax.plot([x0, x1], [y0, y1], 'r');delta_x = x1-x0;delta_y = y1-y0;#画坐标轴if x1>y1:ax.axis([x0-1, x1+1, y0-1, x1+1]);init(ax);else:ax.axis([x0-1, y1+1, y0-1, y1+1]);init(ax);#计算斜率k的值if delta_x == 0:k = 999999999;else:k = delta_y / delta_x;#如果|k|<=1if k>-1 and k<1:while x0<=x1:x = round(x0);y = round(y0);ax.plot(x, y, 'b.');x0 += 1;y0 = y0+k;else:while y0<=y1:x = round(x0);y = round(y0);ax.plot(x, y, 'b.');x0 += 1/k;y0 += 1;plt.show();运⾏截图:中点画线:以下PPT截图来⾃北京化⼯⼤学李辉⽼师代码实现:wimport matplotlib.pyplot as pltimport matplotlib.patches as patchesfrom pylab import *def init(ax):#将主标签设置为1的倍数majorLocator = MultipleLocator(1);#设置主刻度标签的位置,标签⽂本的格式ax.xaxis.set_major_locator(majorLocator);ax.yaxis.set_major_locator(majorLocator);ax.grid(True);if__name__ == '__main__':x0, y0, x1, y1 = map(int, input("请输⼊直线的起点与终点: ").split('')) ax = subplot(title='Midpoint');ax.plot([x0, x1], [y0, y1], 'r');a = y0-y1;b = x1-x0;d = 2*a+b;d1 = 2*a;d2 = 2*(a+b);#画坐标轴if x1>y1:ax.axis([x0-1, x1+1, y0-1, x1+1]);init(ax);else:ax.axis([x0-1, y1+1, y0-1, y1+1]);init(ax);x = x0;y = y0;ax.plot(x, y, 'r.');while(x < x1):if d<0:x += 1;y += 1;d += d2;else:x += 1;d += d1;ax.plot(x, y, 'r.');plt.show()中点画圆法:以下PPT截图来⾃北京化⼯⼤学李辉⽼师import matplotlib.pyplot as pltimport matplotlib.patches as patchesfrom pylab import *def init(ax):#将主标签设置为1的倍数majorLocator = MultipleLocator(1);#设置主刻度标签的位置,标签⽂本的格式ax.xaxis.set_major_locator(majorLocator);ax.yaxis.set_major_locator(majorLocator);ax.grid(True);if__name__ == '__main__':r = int(input("请输⼊半径: "));plt.figure(figsize=(r*0.1, r*0.1));ax = subplot(title='MidPointCircle');d = 1-r;ax.axis([-r-1, r+1, -r-1, r+1]);init(ax);x = 0;y = r;ax.plot(x, y, 'r.');while(x <= y):if d<0:d += 2*x+3;else:d += 2*(x-y)+5;y -= 1;x += 1;ax.plot(x, y, 'r.');ax.plot(y, x, 'r.');ax.plot(x, -y, 'r.');ax.plot(-y, x, 'r.');ax.plot(-x, y, 'r.');ax.plot(y, -x, 'r.');ax.plot(-x, -y, 'r.');ax.plot(-y, -x, 'r.');plt.show()椭圆的扫描转换:以下PPT截图来⾃北京化⼯⼤学李辉⽼师代码实现:import matplotlib.pyplot as pltimport matplotlib.patches as patchesimport mpl_toolkits.axisartist as axisartistfrom pylab import *def init(ax):#设置x轴:空⼼箭头、数值在下⽅ax.axis["x"] = ax.new_floating_axis(0, 0);ax.axis["x"].set_axisline_style("->", size = 1.0);ax.axis["x"].set_axis_direction("bottom");#设置y轴:空⼼箭头、数值在右⽅ax.axis["y"] = ax.new_floating_axis(1, 0);ax.axis["y"].set_axisline_style("->", size = 1.0);ax.axis["y"].set_axis_direction("right");if__name__ == '__main__':a, b = map(int, input("请输⼊椭圆的长、短半径: ").split('')); fig = plt.figure(figsize=(5, 7))#初始化画布ax = axisartist.Subplot(fig, 111, title='MidpointElipse');#将绘图区对象添加到画布中fig.add_axes(ax)init(ax);x = 0;y = b;d1 = b*b+a*a*(-b+0.25); #增量初值ax.plot(x, y, 'r.');ax.plot(x, -y, 'r.');while(b*b*(x+1)<a*a*(y-0.5)): #法向量的x、y不⼀样⼤时if d1<0:d1 += b*b*(2*x+3);x += 1;else:d1 += b*b*(2*x+3)+a*a*(-2*y+2);x += 1;y -= 1;#画四个对称点ax.plot(x, y, 'r.');ax.plot(x, -y, 'r.');ax.plot(-x, y, 'r.');ax.plot(-x, -y, 'r.');#画到了法向量的x=y,即椭圆弧的下半部分d2 = b*b*(x+0.5)*(x+0.5)+a*a*(y-1)*(y-1)-a*a*b*b;while y>0: #终结条件y>0if d2<0:d2 += b*b*(2*x+2)+a*a*(-2*y+3);x += 1;y -= 1;else:d2 += a*a*(-2*y+3);y -= 1;ax.plot(x, y, 'r.');ax.plot(x, -y, 'r.');ax.plot(-x, y, 'r.');ax.plot(-x, -y, 'r.');plt.show()。

实验1中点画线和Bresenham画线算法的实现

实验1中点画线和Bresenham画线算法的实现

实验1中点画线和Bresenham画线算法的实现计算机图形学实验报告实验1 使用画线算法,绘制直线段一.实验目的及要求(1)掌握图形学中常用的三种画线算法:数值微分法、中点画线法和Bresenham画线算法。

(2)掌握绘制直线的程序设计方法。

(3)掌握使用文件来保存直线段的方法。

(4)掌握从文本文件中恢复出直线的方法。

二.实验内容使用VC++ 6.0开发环境,分别实现中点画线算法和Bresenham 画线算法,绘制直线(注意,不能使用VC中已有的绘制直线的函数),并以文本文件的形式保存绘制的结果,可以从文本文件中恢复出以前绘制过的直线。

三.算法设计与分析Bresenham算法绘制直线的程序(仅包含整数运算)。

void MidBresenhamLine(int x0,int y0,int x1,int y1,int color) {int dx,dy,d,UpIncre,DownIncre,x,y;if(x0>x1){x=x1;x1=x0;x0=x;y=y1;y1=y0;y0=y;}x=x0;y=y0;dx=x1-x0;dy=y1-y0;d=dx-2*dy;UpIncre=2*dx-2*dy;DownIncre=-2*dy;while(x<=x1){putpixel(x,y,color);X++;if(d<0){y++;d+=UpIncre;}else d+=DownIncre;}}四.程序调试及运行结果的自我分析与自我评价// testView.cpp : implementation of the CT estView class#include "stdafx.h"#include "test.h"#include "testDoc.h"#include "testView.h"#include // ifstream、ofstream等位于其中#include#include // string类型需要#include "DlgInput.h" //CDlgInput类的头文件using namespace std;#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif// CTestViewIMPLEMENT_DYNCREATE(CTestView, CView)BEGIN_MESSAGE_MAP(CTestView, CView)//{{AFX_MSG_MAP(CTestView)ON_COMMAND(ID_MENUITEM32771, OnMenuitem32771)ON_COMMAND(ID_MENUBRESENHAMLINE, OnMenubresenhamline) ON_COMMAND(ID_MENUCLEARVIEW, OnMenuclearview)ON_COMMAND(ID_FILE_OPEN, OnFileOpen)ON_COMMAND(ID_FILE_SA VE, OnFileSave)//}}AFX_MSG_MAP// Standard printing commandsON_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()// CTestView construction/destructionCTestView::CTestView(){// TODO: add construction code herem_nFlag = -1; // 不是任何绘图类型}CTestView::~CT estView(){}BOOL CTestView::PreCreateWindow(CREATESTRUCT& cs){// TODO: Modify the Window class or styles here by modifying// the CREATESTRUCT csreturn CView::PreCreateWindow(cs);}// CTestView drawingvoid CTestView::OnDraw(CDC* pDC){CTestDoc* pDoc = GetDocument();ASSERT_V ALID(pDoc);// TODO: add draw code for native data hereif(1==m_nFlag) // 中点画线{MidPointLine(m_X0, m_Y0, m_X1, m_Y1, RGB(255,0,0) );}else if(2==m_nFlag) // Bresenham画线{BresenhamLine(m_X0, m_Y0, m_X1, m_Y1, RGB(0,255,0) );}}// CTestView printingBOOL CTestView::OnPreparePrinting(CPrintInfo* pInfo){// default preparationreturn DoPreparePrinting(pInfo);}void CTestView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){// TODO: add extra initialization before printing}void CTestView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){// TODO: add cleanup after printing}// CTestView diagnostics#ifdef _DEBUGvoid CTestView::AssertValid() const{CView::AssertValid();}void CTestView::Dump(CDumpContext& dc) const{CView::Dump(dc);}CTestDoc* CTestView::GetDocument() // non-debug version is inline{ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CT estD oc)));return (CT estDoc*)m_pDocument;}#endif //_DEBUG// CTestView message handlersvoid CTestView::OnMenuitem32771(){// TODO: Add your command handler code herem_nFlag = 1; // 中点画线CDlgInput dlg;if(IDOK==dlg.DoModal()){m_X0=dlg.m_nX0;m_Y0=dlg.m_nY0;m_X1=dlg.m_nX1;m_Y1=dlg.m_nY1;RedrawWindow(); //重绘窗口}}void CTestView::OnMenubresenhamline(){// TODO: Add your command handler code herem_nFlag = 2; // Bresenham画线CDlgInput dlg;if(IDOK==dlg.DoModal()){m_X0=dlg.m_nX0;m_Y0=dlg.m_nY0;m_X1=dlg.m_nX1;m_Y1=dlg.m_nY1;RedrawWindow(); //重绘窗口}}// 算法: 中点画线// 输入: 起点(x0,y0),终点(x1,y1);// 输入要求x0<=x1;void CTestView::MidPointLine( int x0, int y0, int x1, int y1, int color ){CDC * pDC=GetDC();int a,b,d0,d1,d2,d3,d4,d5,d,x,y;a=y0-y1;b=x1-x0; // 之前的设置已经保证始终有x1>=x0d=2*a+b;d0=2*a-b;d1=2*a;d2=2*(a+b);d3=2*b;d4=2*(a-b);d5=a-2*b;x=x0;y=y0;pDC->SetPixel(x,y,color);if(x==x1) // 斜率k为无穷大{if(y<=y1){while(y<=y1){pDC->SetPixel(x,y,color);y++;}}else{while(y>=y1){pDC->SetPixel(x,y,color);y--;}}}// if 斜率k为无穷大else // 斜率k为有限值{// double k=-a/b;// if( k+1>1e-6 && k-1<1e-6 || fabs(k-1)<1e-6 || fabs(k+1)<1e-6) // |k|<=1(即:-1<= k <=1),与1e-6比较是浮点数比较方法if( -b<=-a && -a<=b ) // 用浮点数比较在|k|=1.0f时容易出问题,所以直接用整数比较(将斜率k转换为a与b的比较;之前的设置已经保证b为正数){if(y<=y1){while(x<x1)< p="">{if(d<0){x++;y++;d+=d2;}else{x++;d+=d1;}pDC->SetPixel(x,y,color);}}else{while(x<x1)< p="">{if(d0<0){ x++;d0+=d1;}else{ x++;y--; d0+=d4; }pDC->SetPixel(x,y,color);}}}// if( |k|<=1 )else // |k|>1{if(y<=y1){while(x<x1)< p="">{if(d<0){y++;d+=d3;}else{y++;x++;d+=d2;}pDC->SetPixel(x,y,color);}}else{while(x<x1)< p="">{if(d5<0){ x++;y--; d5+=d4;}else{y--; d5+=-2*b;}pDC->SetPixel(x,y,color);}}}// else( |k|>1 )}// else 斜率k为有限值ReleaseDC(pDC);}// 算法: Bresenham画线// 输入: 起点(x0,y0),终点(x1,y1);// 输入要求x0<=x1;void CTestView::BresenhamLine( int x0, int y0, int x1, int y1, int color ){ CDC * pDC=GetDC();int x,y,dx,dy,e;dx=x1-x0;dy=y1-y0;e=-dx;x=x0;y=y0;while(x<=x1){ pDC->SetPixel(x,y,color);x++;e=e+2*dy;if(e>0){y++;e=e-2*dx;}}}void CTestView::OnMenuclearview(){// TODO: Add your command handler code here m_X0=0;m_Y0=0;m_X1=0;m_Y1=0;RedrawWindow();//重绘窗口}// 打开过去保存的文件,该文件包含直线的端点坐标void CTestView::OnFileOpen(){// TODO: 在此添加命令处理程序代码if( m_nFlag!=1 && m_nFlag!=2 ){MessageBox("请先在菜单中选择绘制直线的方法!","提示",MB_ICONWARNING);return;}CFileDialog dlgFile (TRUE, _T("txt"), _T(""),OFN_FILEMUSTEXIST| OFN_HIDEREADONL Y, _T("线段端点坐标文件(*.txt)|*.txt||"), this);if( IDOK == dlgFile.DoModal()){CString fileName = dlgFile.GetFileName();ifstream rFile;rFile.open(fileName,ios::in);if ( ! rFile.is_open() ){MessageBox("文件打开失败!","提示",MB_ICONW ARNING);return;}CString strLine0;string strLine;int nX,nY;// 起点、终点,两个坐标rFile>>strLine;strLine0 = strLine.c_str();nX = atoi( strLine0.Left( strLine0.Find(",") ) ); // 解析文件,如“220,221”表示一个点的x、y坐标nY = atoi( strLine0.Mid( strLine0.Find(",")+1 ) );m_X0 = nX;m_Y0 = nY;rFile>>strLine;strLine0 = strLine.c_str();nX = atoi( strLine0.Left( strLine0.Find(",") ) );nY = atoi( strLine0.Mid( strLine0.Find(",")+1 ) );m_X1 = nX;m_Y1 = nY;RedrawWindow();rFile.close();}}// 保存当前视图上绘制的所有直线的端点坐标void CTestView::OnFileSave(){// TODO: 在此添加命令处理程序代码CFileDialog dlgFile(FALSE, _T("txt"), _T(""), OFN_OVERWRITEPROMPT, _T("线段端点坐标文件(*.txt)|*.txt||"), this);if( IDOK == dlgFile.DoModal()) // 保存文件{CString strFileName = dlgFile.GetFileName(); // 包含完整路径的文件名称ofstream wFile;wFile.open(strFileName,ios::out|ios::ate|ios::app);if ( ! wFile.is_open() ){MessageBox(strFileName+"文件创建失败!","提示",MB_ICONW ARNING);return;}wFile<<m_x0<<","<<m_y0<<="">wFile<<m_x1<<","<<m_y1<<="">五.实验心得及建议实验心得:Bresenham算法是一种很方便很实用很简单的算法,它对任意斜率的直线段具有通用性。

Bresenham中点画线算法

Bresenham中点画线算法

先标明这转载自/xxxxxx91116/article/details/6295714直线扫描算法之---bresenham改进算法(任何斜率,任何方向)by zxx图形学神马的全都是数学,看来以后我不能搞这个,伤脑筋,所以先把我现在懂得先记录下来吧。

不过呢,我的水平实在有限,对于算法这种东西实在难以说明白,请大家包涵。

书上讲的实在是太过简略,所以这里我把一些简单的推导过程都记录下来:1.重温bresenham未改进算法(斜率在0-1之间的直线)我想要记录的是bresenham改进算法,所以在讲解改进算法之前,我先用一个简单的例子说明一下未改进算法的思想:这是一个斜率k在0-1之间的一条直线,我就用斜率为0-1之间的直线来重温:首先,如图1所示,假设x列的像素已定,其坐标为(x,y),那么下一个坐标一定是:(x+1,y+1)或者(x+1,y)。

而是哪一个取决于d的值,如果d>0.5那么就是(x+1,y+1),如果d<0.5,那么就是(x+1,y),而d是什么呢?当然是斜率了。

(原因如下:y=kx+b当x增加1时:y=kx+k+b所以当x增加1是,y方向的增量是d。

)所以每次我们只需要让d=d+k(k是斜率)即可,当d>=1时,就让d减一,这样就保证了d在0-1之间。

当d>0.5,下一个点取(x+1,y+1)当d<0.5,下一个点取(x+1,y)然后呢,我们为了判断的方便,让e=d-0.5,这样就变成了:当e>0,下一个点取(x+1,y+1)当e<0,下一个点取(x+1,y)2.过渡,重温之后,我们就想要改进,为什么要改进呢?因为我们这里面有0.5,还有k,k里面有dx/dy,这些除法和小数都不是我们想要的,我们想要的是,只有整数,且只有加法的算法,下面就全面讨论一下改进算法。

3.改进算法篇(不同斜率,不同方向)这里,我们主要分为4个角度来说明:A.斜率在0-1只间B.斜率在1-无穷之间C.斜率在0-(-1)之间D.斜率在(-1)-负无穷之间E.两种特殊情况,两条直线。

计算机图形学(三种画线算法)

计算机图形学(三种画线算法)

计算机图形学(三种画线算法)第⼆章:光栅图形学算法1、光栅显⽰器:光栅扫描式图形显⽰器简称光栅显⽰器,是画点设备,可看作是⼀个点阵单元发⽣器,并可控制每个点阵单元的亮度2、由来:随着光栅显⽰器的出现,为了在计算机上处理、显⽰图形,需要发展⼀套与之相适应的算法。

3、研究内容:1>直线段的扫描转换算法2>多边形的扫描转换与区域填充算法3>裁剪算法4>反⾛样算法5>消隐算法⼀、直线段的扫描转换算法1.为了显⽰⼀条直线,就在光栅显⽰器上⽤离散的像素点逼近直线,所以我们就要知道这些像素点的坐标已知P0和P1,利⽤斜截式⽅程,y=kx+b,求出k=(y1-y0)/(x1-x0),b为截距现在k,b已知,x,y未知,现在假设⼀个像素距离为y,即可求出y的值。

因为像素的坐标是整数,所以y值还要进⾏取整处理2.在计算机中加法的运算更快,乘法较慢,故可以把上述⽅法优化来提⾼效率1>数值微分法(DDA)2>中点划线法3>Bresenham算法数值微分法(DDA)-----增量算法(只有⼀个加法)这个式⼦的含义是:当前步的y值等于前⼀步的y值加上斜率k(增量)例⼦:思考:x递增1,y递增k,是否适合任意的k?可改进的点:1>⼀般情况下,k都是⼩数,且每⼀步均要对y四舍五⼊,唯⼀改进的途径是把浮点运算变为整数加法!2>⽅程还有两点式,⼀般式当|k|<=1时,伪代码如下:voidDDALine(int x0,int y0,int x1,int y1,int color){Int x;Float dx,dy,y,k;dx=x1-x0;dy=y1-y0;K=dy/dx;y=y0;For(x=x0,x<=x1;x++){Drawpixel(x,int(y+0.5),color);//drawpixel(x, y, color)在(x, y)像素点绘制颜⾊为color的点Y=y+k;}}中点画线法采⽤直线的⼀般式⽅程:Ax+By+C=0 F(x,y)=0,其中a = y0 - y1, b = x1 - x0,c = x0y1 - x1y0令F(x, y)=0则得出直线⽅程,代⼊ (x0, y0)和(x1, y1),便可得到三个⽅程,可求出a,b,c的值⼀条直线把平⾯分成了三个部分,直线上⽅,直线上,直线下⽅x⽅向上+1,y⽅向上加不加1需判断如何判断Q在M的上⽅还是下⽅?把M点的坐标带⼊⽅程,其中a = y0 - y1, b = x1 - x0分析计算量?两个乘法,四个加法,推导出d的增量公式d的初始值包含⼩数,因此可以⽤2d来代替d实现整数加法,所以d=2a+b伪代码如下:Void MidPointLine(int x0,int y0,int x1,int y1,int color){Int a,b,delta1,delta2,d,x,y;a=y0-y1;b=x1-x0;d=2*a+b;Delta1 = 2*a;Delta2 =2*(a+b);X = x0;Y=y0;//在对应的x,y像素点着⾊putpixel(x,y,GREEN);while(x<x1){if(d<0){x++;y++;d+=delta2;}else{x++;d+=delta1;}//在对应的x,y像素点着⾊putpixel(x,y,GREEN);}Bresenham算法每步的进化:DDA把算法效率提⾼到每步只做⼀个加法中点算法进⼀步把效率提⾼到每步只做⼀个整数加法Bresenham算法提供了⼀个更⼀般的算法,该算法不仅有好的效率,⽽且有更⼴泛的适⽤范围如何把算法的效率也提⾼到整数加法?改进⼀:令e=d-0.5因为d的初值为0,所以e的初值为-0.5,e=e+k,如果e>0,e=e-1改进⼆:在计算e值的情况下还是关于浮点数的计算,所以把浮点数化为整数。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

XX大学实验报告
学院:计信学院专业:班级:姓名学号实验组实验时间20112-03-22 指导教师成绩实验项目名称中点画线算法

理解并掌握中点画线算法,利用相关软件实现中点画线算法。






了解中点画线算法思想。




见教材。






Windows 7 、Visual Studio 2010




根据算法实现中点画线算法。




验内容(1)编写0<k<1中点画线算法,k为斜率;
(2)利用相关软件测试调试中点画线算法保证正确。





程序设计截图如下:

验总结通过这次试验,使我对中点画线算法的思想有了更深的理解(该程序的图形界面参考了网上资料),同时也对计算机图形学产生了更多的兴趣。

指导教


见签名:年月日。

相关文档
最新文档