图形学2
- 格式:doc
- 大小:61.00 KB
- 文档页数:6
实验二直线的生成算法的实现班级 08信计二班学号 20080502086 姓名分数一、实验目的和要求:1、理解直线生成的基本原理2、熟悉直线的生成算法,掌握直线的绘制3、实现直线生成的DDA 中点画法 Bresenham算法4、了解Visual C++等编程环境中常用控件命令与绘图函数,初步掌握在试验设计集成下进行图形处理程序的设计方法二、实验内容:1、了解直线生成的原理直线DDA算法,中点画线算法,Bresenham画线算法2、编程实现DDA算法、Bresenham算法、中点画法绘制直线段三、实验结果分析1.DDA算法// 程序名称:基于 DDA 算法画任意斜率的直线#include <graphics.h>#include <conio.h>// 四舍五入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, 1, 1, 478, GREEN);Line_DDA(1, 478, 638, 1, GREEN);// 按任意键退出getch();closegraph();}2.中点算法// 程序名称:基于中点算法画任意斜率的直线#include <graphics.h>#include <conio.h>// 使用中点算法画任意斜率的直线(包括起始点,不包括终止点)void Line_Midpoint(int x1, int y1, int x2, int y2, int color){int x = x1, y = y1;int a = y1 - y2, b = x2 - x1;int cx = (b >= 0 ? 1 : (b = -b, -1));int cy = (a <= 0 ? 1 : (a = -a, -1));putpixel(x, y, color);int d, d1, d2;if (-a <= b) // 斜率绝对值 <= 1{d = 2 * a + b;d1 = 2 * a;d2 = 2 * (a + b);while(x != x2){if (d < 0)y += cy, d += d2;elsed += d1;x += cx;putpixel(x, y, color);}}else // 斜率绝对值 > 1{d = 2 * b + a;d1 = 2 * b;d2 = 2 * (a + b);while(y != y2){if(d < 0)d += d1;elsex += cx, d += d2;y += cy;putpixel(x, y, color);}}}// 主函数void main(){initgraph(640, 480);// 测试画线Line_Midpoint(100, 1, 1, 478,YELLOW);Line_Midpoint(1, 478, 638, 1, YELLOW);// 按任意键退出getch();closegraph();}3. Bresenham 算法// 程序名称:基于 Bresenham 算法画任意斜率的直线#include <graphics.h>#include <conio.h>// 使用 Bresenham 算法画任意斜率的直线(包括起始点,不包括终止点)void Line_Bresenham(int x1, int y1, int x2, int y2, int color){int x = x1;int y = y1;int dx = abs(x2 - x1);int dy = abs(y2 - y1);int s1 = x2 > x1 ? 1 : -1;int s2 = y2 > y1 ? 1 : -1;bool interchange = false; // 默认不互换 dx、dyif (dy > dx) // 当斜率大于 1 时,dx、dy 互换{int temp = dx;dx = dy;dy = temp;interchange = true;}int p = 2 * dy - dx;for(int i = 0; i < dx; i++){putpixel(x, y, color);if (p >= 0){if (!interchange) // 当斜率 < 1 时,选取上下象素点y += s2;else // 当斜率 > 1 时,选取左右象素点x += s1;p -= 2 * dx;}if (!interchange)x += s1; // 当斜率 < 1 时,选取 x 为步长elsey += s2; // 当斜率 > 1 时,选取 y 为步长p += 2 * dy;}}// 主函数void main(){initgraph(640, 480);// 测试画线Line_Bresenham(100, 1, 1, 478, RED);Line_Bresenham(1, 478, 638, 1, RED);// 按任意键退出getch();closegraph();}实验结果分析三种算法运算结果比较:像素逼近效果由好到差依次为:B算法、DDA算法、中点算法执行速度由快到慢依次为:中点算法、DDA算法、B算法。
深圳大学实验报告课程名称:计算图形学实验名称:二维图形绘制学院:计算机与软件学院专业:计算机科学与技术报告人:学号:班级:同组人:无指导教师:周虹实验时间:2014/10/31实验报告提交时间:2014/11/3教务处制一.实验目的1、能正确使用OpenGL图元产生图画,并且学会使用多种生成图案的方式。
2、能正确设置图元属性,得到不同的绘制效果。
二.实验步骤1、用三角形模式画有颜色填充的太阳,圆心为(-0.5,0.7)2、直线模式,以-0.5,0.7为圆心画一些列直线作为太阳光3、用三角形画树,多边形画树干4、直线模式,以-0.5,0.7为圆心画一小花点缀树5、以三角形模式画一个小山坡,用天蓝色填充6、直线模式,以-0.5,0.7为圆心,以不同大小的直线画一系列小花点缀小山坡7、以不同大小的点形成双色围栏8、用不同的多边形模式画小树,用多边形模式画树干,并染上特别的颜色9、用虚线画零星的小草三.实验结果1、用三角形模式画有颜色填充的太阳,圆心为(-0.5,0.7)2、直线模式,以-0.5,0.7为圆心画一些列直线作为太阳光3、用三角形画树,多边形画树干4、直线模式,以-0.5,0.7为圆心画一小花点缀树5、以三角形模式画一个小山坡,用天蓝色填充6、直线模式,以-0.5,0.7为圆心,以不同大小的直线画一系列小花点缀小山坡7、以不同大小的点形成双色围栏8、用不同的多边形模式画小树,用多边形模式画树干,并染上特别的颜色9、用虚线画零星的小草四.实验心得通过这次实验,我比较深入地理解了二维图形的绘制过程和不同图元相关属性的设置,并学会运用不同的图元组合得到自己想要的画。
本次实验收获良多,主要体现在以下方面:作图时要善于运用函数。
例如在本次实验中涉及到画圆,可是opengl中并没有提供画圆的工具,这时函数就显得尤为重要了。
可是,有了函数还不够,得到函数后要根据自己要的属性选择适当的作图模式。
例如本次画太阳的过程中,一开始我选用GL_LINES的模式,当n趋向无穷大时得到一个圆,可是问题是这个圆是空心的,无法填充红色。
计算机图形学实验报告学号:********姓名:班级:计算机 2班指导老师:***2010.6.19实验一、Windows 图形程序设计基础1、实验目的1)学习理解Win32 应用程序设计的基本知识(SDK 编程);2)掌握Win32 应用程序的基本结构(消息循环与消息处理等); 3)学习使用VC++编写Win32 Application 的方法。
4)学习MFC 类库的概念与结构;5)学习使用VC++编写Win32 应用的方法(单文档、多文档、对话框);6)学习使用MFC 的图形编程。
2、实验内容1)使用WindowsAPI 编写一个简单的Win32 程序,调用绘图API 函数绘制若干图形。
(可选任务)2 )使用MFC AppWizard 建立一个SDI 程序,窗口内显示"Hello,Thisis my first SDI Application"。
(必选任务)3)利用MFC AppWizard(exe)建立一个SDI 程序,在文档视口内绘制基本图形(直线、圆、椭圆、矩形、多边形、曲线、圆弧、椭圆弧、填充、文字等),练习图形属性的编程(修改线型、线宽、颜色、填充样式、文字样式等)。
定义图形数据结构Point\Line\Circle 等保存一些简单图形数据(在文档类中),并在视图类OnDraw 中绘制。
3、实验过程1)使用MFC AppWizard(exe)建立一个SDI 程序,选择单文档;2)在View类的OnDraw()函数中添加图形绘制代码,说出字符串“Hello,Thisis my first SDI Application”,另外实现各种颜色、各种边框的线、圆、方形、多边形以及圆弧的绘制;3)在类视图中添加图形数据point_pp,pp_circle的类,保存简单图形数据,通过在OnDraw()函数中调用,实现线、圆的绘制。
4、实验结果正确地在指定位置显示了"Hello,This is my first SDI Application"字符串,成功绘制了圆,椭圆,方形,多边形以及曲线圆弧、椭圆弧,同时按指定属性改绘了圆、方形和直线。
一、绘制FERGUSON 曲线1,改变各点处的一阶导 数数值,绘制 FERGUSON 曲线进行对比分析A=[100,300;120,200;220,200;270,100;370,100;420, 200;420,300;220,280;100,300];B=[10,-10;30,-30;30,-30;30,-10;20,20;20,20;-20, 20;-20,10;20,-20];Q=[2,-2,1,1;-3,3,-2,-1;0,0,1,0;1,0,0,0]; plot(A(:,1),A(:,2)); [m, n]=size(A); hold on for i=1:m-1for t=0:0.001:1 T=[tA3F2,t,1];Px=[A(i,1),A(i+1,1),B(i,1),B(i+1,1)]; Py=[A (i, 2),A(i+1,2),B (i, 2),B(i+1,2)]; x=T*Q*Px :y=T*Q*Py' plot(x,y, 'r');end end2,FERGUSON 曲线丰满度实验姓名学号所使用的语言 完成日期MATLAB 2016/5/9截图部分B=[10,-10;30,-30;30,-30;30,-10;20,20;2 0,20;-20,20;-20,10;20,-20];B=[210,-210;230,-230;230,-230;230,-210;220,240;250,250;-210,230;-220,210;220,-200];A=[100,300;120,200;220,200;270,100;370,100;420, 200;420,300;220,280;100,300]; B=[10,-10;30,-30;30,-30;30,-10;20,20;20,20;-20,20;-20,10;20,-20];C=[20,-20;60,-60;60,-60;60,-20;40,40;40,40;-40,40;-40,40;40,-40];D=[40,-40;120,-120;120,-120;120,-40;80,80;80,80 ;-80,80;-80,80;80,-80];Q=[2,-2,1,1;-3,3,-2,-1;0,0,1,0;1,0,0,0];plot(A(:,1),A(:,2));[m, n]=size(A);hold onfor i=1:m-1for t=0:0.001:1T=[tA3F2,t,1];Px=[A(i,1),A(i+1,1),B(i,1),B(i+1,1)];Py=[A (i, 2),A(i+1,2),B (i, 2),B(i+1,2)];x=T*Q*Px :y=T*Q*Py :Px 1= [A(i,1),A(i+1,1),C(i,1),C(i+1,1)];Py 1=[A (i, 2),A(i+1,2),C(i,2),C(i+1,2)];x1= T*Q*Px1';y1=T*Q*Py1';Px2=[A(i,1),A(i+1,1),D(i,1),D(i+1,1)];Py2=[A (i, 2),A(i+1,2),D(i,2),D(i+1,2)];x2=T*Q*Px2';y2=T*Q*Py2';plot(x,y, 'r');plot(x1,y1, 'r');plot(x2,y2, 'r');endend2、绘制任意二次三点Bezier曲线x=[100 150 200 ];y=[100 50 100 ];plot(x,y, 'k' , ‘n eWidth' ,1); k=le ngth(x);for i=1:k-2for t=0:0.005:1Bx=(t A2-2*t+1)*x(1)+(-2*t A2+2*t)*x (2)+ (t A2)*x(3);By=(t A2-2*t+1)*y(1)+(-2*t A2+2*t)* y(2)+(t A2)* y(3);hold onplot(Bx,By, 'r' , 'Li neWidth' ,2);endend3、绘制三次七点Bezier曲线clear all hold onB1=[100,300;120,200;220,200;270,100];B2=[270,100;370,100;420,200;420,300]plot(B1(:,1),B1(:,2), '-b');plot(B2(:,1),B2(:,2), '-b');for t=0:0.001:1P=[t*t*t t*t t 1];Q=[-1,3,-3,1;3,-6,3,0;-3,3,0,0;1,0,0,0];P仁P*Q*B1;plot(P1(:,1),P1(:,2), '.b' , 'markersize' ,10);P仁P*Q*B2;plot(P1(:,1),P1(:,2), '.b' , 'markersize' ,10); end三、绘制B样条曲线1、绘制均匀二次三点B样条曲线x=[100 150 200 250 300 350 400 450 500];y=[100 50 100 50 150 50 100 50 100];plot(x,y, 'k' , ‘n eWidth' ,1);k=le ngth(x);B=1/2;for i=1:k-2for t=0:0.005:1Bx=B*(tA2-2*t+1)*x(i)+B*(-2*L2+2*t+1)*x(i+1)+B*(t A2)*x(i+2);By=B*(t A2-2*t+1)*y(i)+B*(-2*t A2+2*t+1)*y(i+1)+B*(t A2)*y(i+2);hold onplot(Bx,By, 'r' , 'Li neWidth' ,2);endend2、绘制三次B样条曲线x=[100 120 220 270 370 420 420 ];y=[300 200 200 100 100 200 300 ];plot(x,y, 'k' , 'Li neWidth' ,1);k=le ngth(x);B=1/6;for i=1:k-3for t=0:0.005:1Bx=B*(-t A 3+3*t A2-3*t+1)*x(i)+B*(3*t A3-6*t A2-0*t +4)*x(i+1)+ B*(-3*t A3+3*t A2+3*t+1)*x(i+2)+B*(1*t A3-0*t A2-0* t+0)*x(i+3); By=B*(-t A 3+3*t A2-3*t+1)*y(i)+B*(3*t A3-6*t A2-0*t +4)*y(i+1)+B*(-3*t A3+3*t A2+3*t+1)*y(i+2)+B*(1*t A3-0*t A2-0* t+0)*y(i+3);plot(Bx,By,'r' , 'LineWidth' ,2);endend3、在同一控制顶点下(四个控制定点)绘制三次Bezier曲线和三次B样条曲线hold onx=[220 270 300 320 340 360 370 420 ];y=[200 100 150 150 150 150 100 200 ]; plot(x,y, '-b' , 'Li neWidth' ,2);plot(x,y, '*r' , 'Lin eWidth' ,3);k=length(x); B=1/6;for i=1:k-3for t=0:0.001:1Bx=B*(-t A 3+3*t A2-3*t+1)*x(i)+B*(3*t A3-6*t A2-0*t+4)*x(i+1)+ ...B*(-3*t A3+3*t A2+3*t+1)*x(i+2)+B*(1*t A3-0*t A2-0* t+0)*x(i+3);By=B*(-t A3+3*t A2-3*t+1)*y(i)+B*(3*t A3-6*t A2-0*t +4)*y(i+1)+ ...B*(-3*t A3+3*t A2+3*t+1)*y(i+2)+B*(1*t A3-0*t A2-0* t+0)*y(i+3);plot(Bx,By, 'r' , 'Li neWidth' ,2);endend四、有理曲线绘制绘制有理二次Bezier曲线x=[100 150 200 250 300 350 400 450 500];y=[100 50 100 50 150 50 100 50 100];plot(x,y, 'k' , 'Li neWidth' ,1);k=le ngth(x);B=1/2;for t=0:0.005:1Bx=(B*(tA2-2*t+1)*x(i)+B*(-2*L2+2*t+1)*x(i+1)+B*(tA2)*x(i+2))/(B*(tA2-2*t+1)+B*(-2*L2+2*t+1)+…B*(t A2));By=(B*(t A2-2*t+1)*y(i)+B*(-2*t A2+2*t+1)*y(i+1)+B*(t A2)*y(i+2))/(B*(t A2-2*t+1)+B*(-2*t A2+2*t+1)+…B*(t A2));hold onplot(Bx,By, 'r' , 'Li neWidth' ,2);endend均匀有理B样条曲线绘制有理三次B样条曲线hold on各种参数图形x=[220 270 300 320 340 370 420 ];y=[200 100 140 150 130 100 200 ]; plot(x,y, '-b' , 'Lin eWidth' ,2);k=length(x); B=1/6;for i=1:k-3for t=0:0.001:1Bx=(B*(-t A3+3*t A2-3*t+1)*x(i)+B*(3*t A3-6*t A2-0* t+4)*x(i+1)+ ...B*(-3*t A3+3*t A2+3*t+1)*x(i+2)+B*(1*t A3-0*t A2-0* t+0)*x(i+3))/(B*(-t A3+3*t A2-3*t+1)+B*(3*t A3-6*t A2-0*t+4)+ ...B*(-3*t A3+3*t A2+3*t+1)+B*(1*t A3-0*t A2-0*t+0));By=(B*(-t A3+3*t A2-3*t+1)*y(i)+B*(3*t A3-6*t A2-0* t+4)*y(i+1)+ ...B*(-3*t A3+3*t A2+3*t+1)*y(i+2)+B*(1*t A3-0*t A2-0*。
贵州大学实验报告学院:计信学院专业:计科班级:计科101X(1)=0;Y(1)=R; while y>x if d<0d=d+2*x+3; %取E 点 elsed=d+2*(x-y)+5;%取SE 点 y=y-1; end x=x+1; X(x+1)=x; Y(x+1)=y; end%利用对称性求其它七个八分圆 X1=Y;Y1=X; X2=-Y;Y2=X; X3=-X;Y3=Y; X4=Y;Y4=-X; X5=X;Y5=-Y; X6=-X;Y6=-Y; X7=-Y;Y7=-X;plot(X,Y,X,Y,'o',X1,Y1,X2,Y2,X3,Y3,X4,Y4,X5,Y5,X6,Y6,X7,Y7); title('R=5');算法分析:二阶差分法:利用二阶差分降低增量的阶数二阶差分(降低增量的阶数,用差分法消除中点算法中的乘法运算)。
中点算法中:1,如在现有点p(x p ,y p )上,对p+1点选择了E(x p +1,y p )点 (1)增量ΔE二阶差分增量为:2=∆-∆old newE E (2)增量ΔSE32+=∆i x E 5)(2+-=∆i i y x SE 32+=∆p old x E 3)1(2++=∆p new x E ⎩⎨⎧≥∆+<∆+=+001i ii i i i i d SE d d E d d二阶差分增量为:2=∆-∆oldnew SE SE2,如在现有点p(x p ,y p )上,对p+1点选择了SE(x p +1,y p -1)点 (1)增量ΔE二阶差分增量为:2=∆-∆old new E E(2)增量ΔSE二阶差分增量为:4=∆-∆old new SE SE算法步骤:1,依据上一次迭代中的d 的符号来选择现在点E 或SE (d0=1-R); 2,用在上一次迭代计算的和来计算新的d ;3,用移到新象素点的二次差分值,并用它来更新和移到下一点。
计算机科学系实验报告(首页)课程名称计算机图形学班级08网(1)实验名称光栅直线圆弧生成指导教师季军杰姓名杨志航学号081401229 日期2011.11.10一、实验目的(1) 理解bresenham原理(2) 掌握bresenham算法画直线的方法(3) 掌握bresenham算法画圆的方法二、实验设备与环境操作系统xp微型计算机平台,编程环境:visual c++6.0三、实验内容、程序清单及运行结果实验原理:1.bresenham算法画直线设直线从起点(x1, y1)到终点(x2, y2)。
直线可表示为方程y =mx+b,其中b=y1-m*x1 ,m=(y2-y1)/(x2-x1)=dy/dx;此处的讨论直线方向限于1a 象限(图1-3),当直线光栅化时,x 每次都增加1 个单元,设x 像素为(xi,yi)。
下一个像素的列坐标为xi+1,行坐标为yi,或者递增1 为yi+1,由y 与yi 及yi+1 的距离d1 及d2 的大小而定。
计算公式为y=m(xi+1)+ b (1.1)d1 = y - yi (1.2)d2 = yi +1 - y (1.3)如果d1-d2>0,则yi+1=yi+1,否则yi+1=yi。
式(1.1)、(1.2)、(1.3)代入d1-d2,再用dx 乘等式两边,并以Pi=(d1-d2) dx 代入上述等式,得Pi = 2xidy-2yidx+2dy+(2b-1) dx (1.4)d1-d2 是用以判断符号的误差。
由于在1a 象限,dx 总大于0,所以Pi 仍旧可以用作判断符号的误差。
Pi+1 为Pi+1 = Pi+2dy-2(yi+1-yi) dx (1.5)求误差的初值P1,可将x1、y1 和b 代入式(2.4)中的xi、yi 而得到P1 = 2dy-dx综述上面的推导,第1a 象限内的直线Bresenham 算法思想如下:● ⒈画点(x1, y1),dx=x2-x1,dy=y2-y1,计算误差初值P1=2dy-dx,i=1;● ⒉求直线的下一点位置xi+1 = xi + 1 如果Pi>0,则yi+1=yi+1,否则yi+1=yi;● ⒊画点(xi+1, yi+1);● ⒋求下一个误差Pi+1,如果Pi>0,则Pi+1=Pi+2dy-2dx,否则Pi+1=Pi+2dy;● ⒌i=i+1;如果i<dx+1 则转步骤2;否则结束操作。
关键代码:void CMyView::Bresenhamline(int xa, int ya, int xb, int yb,int color) {CDC* pDC=GetDC();int dx,dy,x,y,p;int i;int c=color/*RGB(0,0,255)*/;dx=xb-xa;dy=yb-ya;x=xa;y=ya;/***竖线处理***/if(dx==0 && dy!=0){if(dy>0){for(i=0; i<dy; i++){pDC->SetPixel(xa,ya+i,c);}}if(dy<0){for(i=0; i>dy; i--){pDC->SetPixel(xa,ya+i,c);} }}/***横线处理***/if(dy==0 && dx!=0){if(dx>0){for(i=0; i<dx; i++){pDC->SetPixel(xa+i,ya,c);}}if(dx<0){ for(i=0; i>dx; i--){pDC->SetPixel(xa+i,ya,c);}}}/***********其他处理坐标域分成八个区域********************/if(abs(dx)>abs(dy)){/**1a**/if(dx>0 && dy>0) {p=2*dy-dx;pDC->SetPixel(x,y,c);while(x<xb){x++;if(p>0){y++;p=p+2*dy-2*dx;}else{p=p+2*dy; }pDC->SetPixel(x,y,c);}}/**4a**/if(dx>0 && dy<0) {p=-2*dy-dx;pDC->SetPixel(x,y,c);while(x<xb){x++;if(p>0){y--;p=p-2*dy-2*dx;}else{p=p-2*dy;}pDC->SetPixel(x,y,c);}}/**2a**/if(dx<0 && dy>0){p=-2*dy-dx; pDC->SetPixel(x,y,c);while(x>xb){x--;if(p>0){p=p-2*dy;}else{y++;p=p-2*dy-2*dx;}pDC->SetPixel(x,y,c);}}/**3a**/if(dx<0 && dy<0) {p=2*dy-dx;pDC->SetPixel(x,y,c);while(x>xb){x--;if(p>0){p=p+2*dy;}else{ y--; p=p+2*dy-2*dx; }pDC->SetPixel(x,y,c);}}}else{/**1b**/if(dy>0 && dx>0) {p=2*dx-dy;pDC->SetPixel(x,y,c);while(y<yb){y++;if(p>0){x++;p=p+2*dx-2*dy;}else{p=p+2*dx;}pDC->SetPixel(x,y,c);}}/**2b**/if(dy>0 && dx<0) { p=-2*dx-dy;pDC->SetPixel(x,y,c);while(y<yb) {y++;if(p>0){x--;p=p-2*dx-2*dy;}else{p=p-2*dx;}pDC->SetPixel(x,y,c);}}/**4b**/if(dy<0 && dx>0) {p=-2*dx-dy;pDC->SetPixel(x,y,c);while(y>yb){y--;if(p>0){p=p-2*dx;}else{x++;p=p-2*dx-2*dy;}pDC->SetPixel(x,y,c);}}/**3b**/if(dy<0 && dx<0) { p=2*dx-dy;pDC->SetPixel(x,y,c);while(y>yb){y--;if(p>0){p=p+2*dx; }else{x--;p=p+2*dx-2*dy;}pDC->SetPixel(x,y,c);}}}}2.bresenham算法画圆的原理设圆的半径为r。
先考虑圆心在(0, 0),并从x=0、y=r 开始的顺时针方向的1/8 圆周的生成过程。
在这种情况下,x 每步增加1,从x=0 开始,到x=y 结束。
即有xi+1 = xi + 1 相应的yi+1 则在两种可能中选择:yi+1 =yi 或者yi+1 = yi-1。
选择的原则是考察精确值y 是靠近yi 还是靠近yi-1(图1-8),计算式为y2 = r2-(xi+1)2d1 = yi2-y2 = yi2-r2+(xi+1)2d2 = y2-(yi-1)2 =r2-(xi+1)2-(yi-1)2 令pi=d1-d2,并代入d1、d2,则有pi = 2(xi+1)2 + yi2 + (yi-1)2-2r2 (1.6)pi 称为误差。
如果pi<0 则yi+1=yi,否则yi+1=yi-1。
pi 的递归式为pi+1 = pi + 4xi +6+2(yi2+1- yi2) -2(yi+1-yi) (1.7)pi 的初值由式(1.6)代入xi=0,yi=r 而得p1 = 3-2r (1.8)根据上面的推导,圆周生成算法思想如下:⒈求误差初值,p1=3-2r,i=1,画点(0, r);⒉求下一个光栅位置,其中xi+1=xi+1,如果pi<0 则yi+1=yi,否则yi+1=yi-1;⒊画点(xi+1, yi+1);⒋计算下一个误差,如果pi<0 则pi+1=pi+4xi+6,否则pi+1=pi+4(xi-yi)+10;⒌i=i+1,如果x=y 则结束,否则返回步骤2。
关键代码:void CMyView::BresenhamCircle(int xx,int yy,int rr){CDC * pDC=GetDC();int xc=xx,yc=yy,radius=rr,c=RGB(0,0,225);int x=0,y=radius,p=3-2*radius;while(x<y){ pDC->SetPixel(xc+x,yc+y,c);pDC->SetPixel(xc-x,yc+y,c);pDC->SetPixel(xc+x,yc-y,c);pDC->SetPixel(xc-x,yc-y,c);pDC->SetPixel(xc+y,yc+x,c);pDC->SetPixel(xc-y,yc+x,c);pDC->SetPixel(xc+y,yc-x,c);pDC->SetPixel(xc-y,yc-x,c);if(p<0)p=p+4*x+6;else{p=p+4*(x-y)+10;y-=1;}x+=1;}if(x==y){pDC->SetPixel(xc+x,yc+y,c);pDC->SetPixel(xc-x,yc+y,c);pDC->SetPixel(xc+x,yc-y,c);pDC->SetPixel(xc-x,yc-y,c);pDC->SetPixel(xc+y,yc+x,c);pDC->SetPixel(xc-y,yc+x,c);pDC->SetPixel(xc+y,yc-x,c);pDC->SetPixel(xc-y,yc-x,c);}}运行结果:四、实验结论、实验体会通过实验,我对bresenham原理有了一些了解,初步学会的用bresenham算法画直线和画圆,但是还不是掌握的很好。