计算机图形学实验二
- 格式:docx
- 大小:128.84 KB
- 文档页数:8
实验二: 直线的生成算法的实现班级 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之间。
实验二直线的生成算法的实现班级 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算法。
《计算机图形学》实验报告(实验二:图形填充算法)一、实验目的及要求用两种方法做图形的填充算法!二、理论基础1.边填充算法对于每一条扫描线和每条多边形的交点(x1,y1),将该扫描线上的交点右方的所有像素取补。
2.种子填充算法利用栈来实现种子填充算法。
种子像素入栈,当栈非空时重复执行如下步骤:将栈顶像素出栈,将出栈像素置成多边形色,按左,上,右,下顺序检查与出栈像素相邻的四个像素,若其中某个像素不再边界且未置成多边形,则把该像素入栈!三、算法设计与分析1、边填充算法void CEdge_mark_fillView::OnDraw(CDC* pDC){CEdge_mark_fillDoc* pDoc = GetDocument();ASSERT_V ALID(pDoc);int d[500][500]={0};int inside;int x,y;Bresenham(80,101,100,400,d);Bresenham(100,300,290,400,d);Bresenham(292,400,382,50,d);Bresenham(380,50,202,150,d);Bresenham(200,150,82,101,d);for(y=0;y<500;y++){inside=0;for(x=0;x<500;x++){if(d[x][y]==1)if(d[x+1][y]!=1){inside=!(inside);}if(inside!=0)pDC->SetPixel(x,y,12);}}}2、种子填充int x=299,y=51;COLORREF oldcolor;COLORREF newcolor;oldcolor=RGB(256,256,256);newcolor=RGB(123,123,123);pDC->MoveTo (40,40);pDC->LineTo (80,40);pDC->LineTo (70,80);pDC->LineTo (40,40);FloodFill(51,51,RGB(255,255,255),RGB(0,0,255));pDC->LineTo (40,40);void CMyView::FloodFill(int x,int y,COLORREF oldcolor,COLORREF newcolor) {CDC* pDC;pDC=GetDC();if(pDC->GetPixel(x,y)==oldcolor){pDC->SetPixel(x,y,newcolor);FloodFill(x,y-1,oldcolor,newcolor);FloodFill(x,y+1,oldcolor,newcolor);FloodFill(x-1,y,oldcolor,newcolor);FloodFill(x+1,y,oldcolor,newcolor);}四、程序调试及结果的分析1、2、四、实验心得及建议由于很多不会,所以这次没能按时当堂完成,下来花了不少时间才弄出来,第二种尤其比较麻烦,在同学的帮助下才做出来了。
深圳大学实验报告课程名称:计算图形学实验名称:二维图形绘制学院:计算机与软件学院专业:计算机科学与技术报告人:学号:班级:同组人:无指导教师:周虹实验时间: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*。
实验报告模板《计算机图形学》实验报告一、实验目的及要求1.实习三维图形的坐标系之间的变换;2.三维图形几何变换;3.掌握三维图形的坐标系之间的变换算法及三维图形几何变换的原理和实现;4.实现二维图形的基本变换(平移、旋转、缩放、错切、对称、复合等);5.实现三维图形的基本变换(平移、旋转、缩放、复合等);二、理论基础在齐次坐标理论下,二维图形几何变换矩阵可用下式表示:⎪⎪⎪⎭⎫⎝⎛===ifchebgdaTnkxx kk2,1,0,)(ϕ平移变换:[x* y* 1] =[x y 1] *0000001ts⎛⎫⎪⎪⎪⎝⎭=[t*x s*y 1]比例变换:[x* y* 1]=[x y 1] *1000101m n⎛⎫⎪⎪⎪⎝⎭=[m+x n+y 1]旋转变换:在平面上的二维图形饶原点逆时针旋转Ө角,变换矩阵为[x* y* 1]=[x y 1] *cos sin0sin cos0001θθθθ⎛⎫⎪- ⎪⎪⎝⎭= [x*cosө-y*sinө]复合变换:以上各种变换矩阵都是以原点为参照点,当以任意参照点进行变换的时候,我们就要用到复合变换矩阵。
三维变换类似于二维,在画图时,把三维坐标转换为二维即可。
三、算法设计与分析二维变换:#define dx 50#define dy 100void CCGWithVCView::OnTransScale() //平移(50,100){// TODO: Add your command handler code here// AfxMessageBox(_T("Please Insert The Move Change Code!")) ;int m[4][2]={{100,50},{50,100},{150,100},{100,50}};int i;int a[2],b[2];CDC * pDC = GetDC();for(i=0;i<3;i++){a[0]=m[i][0];a[1]=m[i][1];b[0]=m[i+1][0];b[1]=m[i+1][1];DDALine(a,b, RGB(0, 200, 255), pDC);}for(i=0;i<3;i++){a[0]=m[i][0]+dx;a[1]=m[i][1]+dy;b[0]=m[i+1][0]+dx;b[1]=m[i+1][1]+dy;DDALine(a,b, RGB(0, 200, 255), pDC);}}#define h 0.1745#include<math.h>void CCGWithVCView::OnTransRotate() //旋转{// TODO: Add your command handler code here// AfxMessageBox(_T("Please Insert The Rotate Change Code!")) ;int m[4][2]={{100,50},{50,100},{150,100},{100,50}};int i;int a[2],b[2];CDC * pDC = GetDC();for(i=0;i<3;i++){a[0]=m[i][0];a[1]=m[i][1];b[0]=m[i+1][0];b[1]=m[i+1][1];DDALine(a,b, RGB(0, 200, 255), pDC);}for(i=0;i<3;i++){a[0]=m[i][0]*cos(h)-m[i][1]*sin(h);a[1]=m[i][1]*cos(h)+m[i][0]*sin(h);b[0]=m[i+1][0]*cos(h)-m[i+1][1]*sin(h);b[1]=m[i+1][1]*cos(h)+m[i+1][0]*sin(h);DDALine(a,b, RGB(0, 200, 255), pDC);}}#define k 2;#define f 2.5void CCGWithVCView::OnTransMove() //缩放{// TODO: Add your command handler code here//AfxMessageBox(_T("Please Insert The Scale Change Code!")) ;int m[4][2]={{100,50},{50,100},{150,100},{100,50}};int i;int a[2],b[2];CDC * pDC = GetDC();for(i=0;i<3;i++){a[0]=m[i][0];a[1]=m[i][1];b[0]=m[i+1][0];b[1]=m[i+1][1];DDALine(a,b, RGB(0, 200, 255), pDC);}for(i=0;i<3;i++){a[0]=m[i][0]*k;a[1]=m[i][1]*f;b[0]=m[i+1][0]*k;b[1]=m[i+1][1]*f;DDALine(a,b, RGB(0, 200, 255), pDC);}}#define n 2#define d 0void CCGWithVCView::OnTransOther(){// TODO: Add your command handler code here//AfxMessageBox(_T("Please Insert The Other Change Code!")) ;int m[4][2]={{100,50},{50,100},{150,100},{100,50}};int i;int a[2],b[2];CDC * pDC = GetDC();for(i=0;i<3;i++){a[0]=m[i][0];a[1]=m[i][1];b[0]=m[i+1][0];b[1]=m[i+1][1];DDALine(a,b, RGB(0, 200, 255), pDC);}for(i=0;i<3;i++){a[0]=m[i][0]+n*m[i][1];a[1]=m[i][1]+d*m[i][0];b[0]=m[i+1][0]+n*m[i+1][1];b[1]=m[i+1][1]+d*m[i+1][0];DDALine(a,b, RGB(0, 200, 255), pDC);}}三维变换:#include<math.h>#define dx 100#define dy 100#define dz 0void CCGWithVCView::OnTransScale() //平移(50,100){// TODO: Add your command handler code here// AfxMessageBox(_T("Please Insert The Move Change Code!")) ;int i;int p2d[6][2];int p3d[6][3]={{400,300,0},{300,400,0},{300,300,10},{275,300,0},{400,300,0},{300,300,10}};for( i=0;i<6;i++){p2d[i][0]=p3d[i][1]-p3d[i][0]/sqrt(2);p2d[i][1]=p3d[i][2]+p3d[i][0]/sqrt(2);}int a[2],b[2];CDC * pDC = GetDC();for(i=0;i<5;i++){a[0]=p2d[i][0];a[1]=p2d[i][1];b[0]=p2d[i+1][0];b[1]=p2d[i+1][1];DDALine(a,b, RGB(0, 200, 255), pDC);}for( i=0;i<6;i++){p2d[i][0]=p3d[i][1]+dy-p3d[i][0]+dx/sqrt(2);p2d[i][1]=p3d[i][2]+dz+p3d[i][0]+dx/sqrt(2);}for(i=0;i<5;i++){a[0]=p2d[i][0];a[1]=p2d[i][1];b[0]=p2d[i+1][0];b[1]=p2d[i+1][1];DDALine(a,b, RGB(0, 0, 255), pDC);}}#define k 0.1745void CCGWithVCView::OnTransRotate() //旋转{// TODO: Add your command handler code here// AfxMessageBox(_T("Please Insert The Rotate Change Code!")) ;int i;int p2d[6][2];int p3d[6][3]={{400,300,0},{300,400,0},{300,300,10},{275,300,0},{400,300,0},{300,300,10}};for( i=0;i<6;i++){p2d[i][0]=p3d[i][1]-p3d[i][0]/sqrt(2);p2d[i][1]=p3d[i][2]+p3d[i][0]/sqrt(2);}int a[2],b[2];CDC * pDC = GetDC();for(i=0;i<5;i++){a[0]=p2d[i][0];a[1]=p2d[i][1];b[0]=p2d[i+1][0];b[1]=p2d[i+1][1];DDALine(a,b, RGB(0, 200, 255), pDC);}for( i=0;i<6;i++){p2d[i][0]=p3d[i][1]*cos(k)-p3d[i][2]*sin(k)-p3d[i][0]/sqrt(2);p2d[i][1]=p3d[i][2]*cos(k)+p3d[i][1]*sin(k)+p3d[i][0]/sqrt(2);}for(i=0;i<5;i++){a[0]=p2d[i][0];a[1]=p2d[i][1];b[0]=p2d[i+1][0];b[1]=p2d[i+1][1];DDALine(a,b, RGB(0, 0, 255), pDC);}}四、程序调试及结果的分析二维:三维:五、实验心得及建议在实验过程中,尽管过程中任由许多不会的地方,而且有待于今后的提高和改进,但我加深了对书本上知识的理解与掌握,同时也学到了很多书本上没有东西,并积累了一些宝贵的经验,这对我以后的学习与工作是不无裨益的。
图形学实验报告图形学实验报告概述:在本次图形学实验中,我们将探索和学习计算机图形学的基本概念和技术。
通过实验,我们深入了解了图形学的原理和应用,以及如何使用计算机生成和处理图像。
实验一:像素和颜色在这个实验中,我们学习了图像是由像素组成的,每个像素都有自己的颜色值。
我们使用了Python编程语言和PIL库来创建一个简单的图像,并设置了不同的像素颜色。
通过改变像素的颜色值,我们可以创建出各种各样的图像效果。
实验二:坐标系统和变换在这个实验中,我们学习了坐标系统和图形变换。
我们使用OpenGL库来创建一个简单的二维图形,并通过平移、旋转和缩放等变换操作来改变图形的位置和形状。
这些变换操作使我们能够在屏幕上创建出各种不同的图案和效果。
实验三:线段和多边形在这个实验中,我们学习了如何使用线段和多边形来绘制图形。
我们使用了Bresenham算法来绘制直线,并学习了如何使用多边形填充算法来填充图形。
通过这些技术,我们可以创建出更加复杂和精细的图像。
实验四:光照和阴影在这个实验中,我们学习了光照和阴影的原理和应用。
我们使用了光照模型来模拟光线的传播和反射,以及计算物体的明暗效果。
通过调整光照参数和材质属性,我们可以创建出逼真的光照和阴影效果。
实验五:纹理映射和渲染在这个实验中,我们学习了纹理映射和渲染的概念和技术。
我们使用了纹理映射来将图像贴到三维物体表面,以增加物体的细节和真实感。
通过渲染技术,我们可以模拟光线的折射和反射,以及创建出逼真的材质效果。
实验六:三维建模和动画在这个实验中,我们学习了三维建模和动画的基本原理和方法。
我们使用了三维建模工具来创建三维模型,并学习了如何使用关键帧动画来实现物体的运动和变形。
通过这些技术,我们可以创建出逼真的三维场景和动画效果。
总结:通过这次图形学实验,我们深入了解了计算机图形学的原理和应用。
我们学习了像素和颜色、坐标系统和变换、线段和多边形、光照和阴影、纹理映射和渲染,以及三维建模和动画等技术。
计算机图形学实验指导书信息科学技术学院二○一三年十一月计算机图形学实验报告实验名称直线、圆弧及曲线的生成算法评分实验日期2013 年11 月 6 日指导教师姓名专业班级11地信学号2011083027一、实验目的1、几种直线生成算法的比较,特别掌握用Bresenham直线生成算法。
2、掌握用像素点法直接生成其它曲线的方法。
二、实验要求1、用不同的生成算法在屏幕上绘制出直线的图形,对不同的算法可设置不同的线形或颜色表示区别。
2、用Bresenham生成算法在屏幕上绘制出圆弧的图形,用动画的方式表演图形的生成。
三、关键算法及实现原理1、有关直线生成算法有:DDA(数值微分)直线算法、逐点比较法、直线Bresenham 生成算法。
直线Bresenham生成算法思想如下(第一象限,且斜率k<1的情况图2-1 a 中的1a):1)画点(x1,y1),dx=x2-x1,dy=y2-y1,计算误差初值P1=2dy-dx,i=1;2)求直线下一点位置x i+1=x i+1 如果P i>0,则y i+1=y i+1,否则y i+1=y i;3)画点(x i+1,y i+1);4)求下一个误差P i+1点,如果P i>0,则P i+1=P i+2dy-2dx,否则P i+1=P i+2dy;5)i=i+1,如果i<dx+1则转步骤2,否则结束操作。
Bresenham生成算法的优点如下;1)不必计算直线的斜率,因此不做除法。
2)不用浮点数,只用整数。
3)只做整数加减运算和乘2运算,而乘2运算可以用移位操作实现。
Bresenham算法的速度很快,并适于用硬件实现。
对于图2-1 a中的2a,只需将x i+1=x i+1改为x i+1=x i-1。
对于图2-1 a中的1b,斜率k>1的情况,可交换变量x和y,y每次长1个单位。
对P i进行判断,x i+1=x i或x i+1=x i+1。
2、有关圆弧生成算法有:逐点比较法、DDA(数值微分)直线算法、圆的Bresenham生成算法。
圆的生成算法一般将圆划分为8等份,只需计算(900,450)的八分之一圆弧,其它用对称法求得(参见图2-1 b)。
Bresenham生成算法思想如下(第一象限,且斜率k<1的情况):1)计算误差初值P1=3-2r,i=1,画点(0,r);2)求下一个光栅点位置x i+1=x i+1 如果P i<0,则y i+1=y i,否则y i+1=y i-1;3)画点(x i+1,y i+1);4)求下一个误差P i+1点,如果P i<0,则P i+1=P i+2x i+6,否则P i+1=P i+4(x i-y i)+10;5) i=i+1,如果x=y则结束操作,否则转步骤2。
圆Bresenham算法的算式简单,只需做加减法和乘4运算适当选取坐标,将屏幕分成几个区域性,在每个区域内实现一种算法,生成一个图形。
也可用delay实现延时实现动画。
四、程序调试中的问题改到安装目录下o1b2b2a3a3b4b4a1a3b4b3a2ao4a1a1b2b图2-1 a 直线方向的8个象限图2-1 b 圆心在(0,0)点圆周(y,x)(-y,x)(x,y)(y,-x)(-y,-x)(-x,-y)(-x,y)生成时的对称变换(x ,y )11(x ,y )22(x,-y)五、程序运行结果或数据六、实验收获及体会直线的生成是图形学中最基本,也是最常见的图形生成,其原理与实现方法直接关系到其他复杂图形生成的效率,而且存在许多需要解决的问题。
椭圆是二次曲线中最简单的,算法的巧妙之处是通过增量的方法判断误差相的符号,通过整数、比较等方法大大提高了计算机的实现效率。
七、参考源程序(可附页)数值微分法生成斜率小于90的直线#include <graphics.h>#include <math.h>#define ROUND(a) ((int)(a+0.5))#define OX 320#define OY 240void lineDDA (int xa, int ya, int xb, int yb, int color);void setpixel (int x, int y, int color);main(){int gdrive=DETECT, gmode=0;initgraph(&gdrive, &gmode, "C:\\TC");setbkcolor(BLACK);line (0, OY, 2*OX, OY);line (OX, 0, OX, 2*OY);lineDDA (10, 100, 0, 0, RED);getch ();closegraph();return 0;}void lineDDA (int xa, int ya, int xb, int yb, int color)int dx = xb - xa;int dy = yb - ya;int steps, i;float xIncrement, yIncrement;float x=xa;float y=ya;if(abs(dx) > abs(dy))steps = abs(dx);elsesteps = abs(dy);xIncrement = dx/(float)steps;yIncrement = dy/(float)steps;putpixel (ROUND(x), ROUND(y), color);for (i=0; i<steps; i++){x += xIncrement;y += yIncrement;setpixel (ROUND(x), ROUND(y), color);}return;}void setpixel (int x, int y, int color){putpixel (OX+x, OY-y, color);return;}椭圆#include <dos.h>#include <graphics.h>#include <math.h>#include <bios.h>#include <stdio.h>#define RADIAN(angle) 3.14159*angle/180int direction;void rotate(int x0,int y0,int *x,int *y,double angle){double r=sqrt((*y-y0)*(*y-y0)+(*x-x0)*(*x-x0)),a0=atan2(*x-x0,*y-y0); if(direction){*x=x0+r*cos(a0+angle);*y=y0+r*sin(a0+angle);}else{*x=x0+r*cos(a0-angle);*y=y0+r*sin(a0-angle);}void myellipse(int x0,int y0,int a,int b,int angle0){int x,y;double r=0.0,end=RADIAN(360),angle=RADIAN(angle0);x=x0+a;y=y0;rotate(x0,y0,&x,&y,angle);moveto(x,y);for(r=0.0;r<=end;r+=0.01){x=x0+a*cos(r);y=y0+b*sin(r);rotate(x0,y0,&x,&y,angle);lineto(x,y);}}main(){int gdriver=DETECT,gmode,angle=0;int ch,x0,y0,a,b; char c;FILE *fp;printf("if you want input,please press I or i,if you want to call saved file,press anykey\n");scanf("%c",&c);if(c=='i'||c=='I'){printf("input x0,y0,a,b,direction:\n");scanf("%d%d%d%d%d",&x0,&y0,&a,&b,&direction);if((fp=fopen("e:\ellipse.txt","w"))==NULL){printf("cannot open the file! \n");exit(0);}fprintf(fp,"%d %d %d %d %d",x0,y0,a,b,direction);fclose(fp);}else{if((fp=fopen("e:\ellipse.txt","r"))==NULL){printf("cannot open the file! \n");exit(0);}fscanf(fp,"%d%d%d%d%d",&x0,&y0,&a,&b,&direction);fclose(fp);initgraph(&gdriver,&gmode,"c:\\tc");while(ch!=0x1c0d){cleardevice();myellipse(x0,y0,a,b,angle);ch=bioskey(0);angle+=30;}closegraph();}椭圆#include <dos.h>#include <graphics.h>#include <math.h>#include <bios.h>#include <stdio.h>#define RADIAN(angle) 3.14159*angle/180int direction;void rotate(int x0,int y0,int *x,int *y,double angle){double r=sqrt((*y-y0)*(*y-y0)+(*x-x0)*(*x-x0)),a0=atan2(*x-x0,*y-y0); if(direction){*x=x0+r*cos(a0+angle);*y=y0+r*sin(a0+angle);}else{*x=x0+r*cos(a0-angle);*y=y0+r*sin(a0-angle);}}void myellipse(int x0,int y0,int a,int b,int angle0){int x,y;double r=0.0,end=RADIAN(360),angle=RADIAN(angle0);x=x0+a;y=y0;rotate(x0,y0,&x,&y,angle);moveto(x,y);for(r=0.0;r<=end;r+=0.01){x=x0+a*cos(r);y=y0+b*sin(r);rotate(x0,y0,&x,&y,angle);lineto(x,y);}main(){int gdriver=DETECT,gmode,angle=0;int ch,x0,y0,a,b; char c;FILE *fp;printf("if you want input,please press I or i,if you want to call saved file,press anykey\n");scanf("%c",&c);if(c=='i'||c=='I'){printf("input x0,y0,a,b,direction:\n");scanf("%d%d%d%d%d",&x0,&y0,&a,&b,&direction);if((fp=fopen("e:\ellipse.txt","w"))==NULL){printf("cannot open the file! \n");exit(0);}fprintf(fp,"%d %d %d %d %d",x0,y0,a,b,direction);fclose(fp);}else{if((fp=fopen("e:\ellipse.txt","r"))==NULL){printf("cannot open the file! \n");exit(0);}fscanf(fp,"%d%d%d%d%d",&x0,&y0,&a,&b,&direction);fclose(fp);}initgraph(&gdriver,&gmode,"c:\\tc");while(ch!=0x1c0d){cleardevice();myellipse(x0,y0,a,b,angle);ch=bioskey(0);angle+=30;}closegraph();}。