计算机图形学实验二
计算机图形学实验二:直线的生成算法的实现

实验二: 直线的生成算法的实现班级 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、四、实验心得及建议由于很多不会,所以这次没能按时当堂完成,下来花了不少时间才弄出来,第二种尤其比较麻烦,在同学的帮助下才做出来了。
计算机图形学_实验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

计算机图形学实验报告学号:********姓名:班级:计算机 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"字符串,成功绘制了圆,椭圆,方形,多边形以及曲线圆弧、椭圆弧,同时按指定属性改绘了圆、方形和直线。
计算机图形学基础实验指导书

计算机图形学基础实验指导书目录实验一直线的生成 ............................................................... -..2.-实验二圆弧及椭圆弧的生成........................................................ -..3 -实验三多边形的区域填充 ......................................................... - (4)-实验四二维几何变换 ............................................................. -..5.-实验五裁剪算法 ................................................................. -..6.-实验六三维图形变换 ............................................................. -..7.-实验七BEZIER 曲线生成......................................................... -..8.-实验八交互式绘图技术实现........................................................ -..10-实验一直线的生成一、实验目的掌握几种直线生成算法的比较,特别是Bresenham 直线生成算法二、实验环境实验设备:计算机实验使用的语言: C 或Visual C++ 、OpenGL三、实验内容用不同的生成算法在屏幕上绘制出直线的图形,对不同的算法可设置不同的线形或颜色表示区别。
四、实验步骤直线Bresenham 生成算法思想如下1)画点(x i, y i), dx=x2-x i, dy=y2-y i,计算误差初值P i=2dy-dx , i=1;2)求直线下一点位置x i+i=x i+i 如果P i>0,贝U y i+i=y i+i,否则y i+i=y i;3)画点(x i+i ,y i+i );4)求下一个误差P i+i 点,如果P i>0,贝U P i+i=P i+2dy-2dx,否则P i+i=P i+2dy;i=i+i ,如果i<dx+i 则转步骤2,否则结束操作。
图形学实验报告

图形学实验报告图形学实验报告概述:在本次图形学实验中,我们将探索和学习计算机图形学的基本概念和技术。
通过实验,我们深入了解了图形学的原理和应用,以及如何使用计算机生成和处理图像。
实验一:像素和颜色在这个实验中,我们学习了图像是由像素组成的,每个像素都有自己的颜色值。
我们使用了Python编程语言和PIL库来创建一个简单的图像,并设置了不同的像素颜色。
通过改变像素的颜色值,我们可以创建出各种各样的图像效果。
实验二:坐标系统和变换在这个实验中,我们学习了坐标系统和图形变换。
我们使用OpenGL库来创建一个简单的二维图形,并通过平移、旋转和缩放等变换操作来改变图形的位置和形状。
这些变换操作使我们能够在屏幕上创建出各种不同的图案和效果。
实验三:线段和多边形在这个实验中,我们学习了如何使用线段和多边形来绘制图形。
我们使用了Bresenham算法来绘制直线,并学习了如何使用多边形填充算法来填充图形。
通过这些技术,我们可以创建出更加复杂和精细的图像。
实验四:光照和阴影在这个实验中,我们学习了光照和阴影的原理和应用。
我们使用了光照模型来模拟光线的传播和反射,以及计算物体的明暗效果。
通过调整光照参数和材质属性,我们可以创建出逼真的光照和阴影效果。
实验五:纹理映射和渲染在这个实验中,我们学习了纹理映射和渲染的概念和技术。
我们使用了纹理映射来将图像贴到三维物体表面,以增加物体的细节和真实感。
通过渲染技术,我们可以模拟光线的折射和反射,以及创建出逼真的材质效果。
实验六:三维建模和动画在这个实验中,我们学习了三维建模和动画的基本原理和方法。
我们使用了三维建模工具来创建三维模型,并学习了如何使用关键帧动画来实现物体的运动和变形。
通过这些技术,我们可以创建出逼真的三维场景和动画效果。
总结:通过这次图形学实验,我们深入了解了计算机图形学的原理和应用。
我们学习了像素和颜色、坐标系统和变换、线段和多边形、光照和阴影、纹理映射和渲染,以及三维建模和动画等技术。
山东大学计算机图形学实验报告实验二

学号:2420430689 姓名: QQ
班级: 2014 级
实Байду номын сангаас题目:实现二维平面的基本变换
实验学时:4
实验日期: 2017 年 3 月 28 日
实验目的: 1. 掌握配置 OpenGL 环境的方法; 2. 熟悉 OpenGL 应用程序基本架构; 3. 学习 OpenGL 中的 gl、glu、glut 等库函数进行图形学算法编程和实现。
//填充右部 while (!judgeIfBoundary(x, y)) {
glBegin(GL_POINTS); glVertex2i(x, y); glEnd(); glFlush(); x = x + 1; } int xright = x - 1;
//填充左部 x = savex - 1; while (!judgeIfBoundary(x, y)) {
#include <cmath> #include <stack> #include <glut.h>
using namespace std;
struct mypoint {
GLint x; GLint y;
mypoint(GLint _x, GLint _y) :x(_x), y(_y) {}; mypoint() {}; };
x = x + 1; } } } } } 最后效果
结论分析与体会: 这次实验总的来讲比较繁琐,尤其是在计算校徽坐标的时候,当时是从学校官网 上找了一个比较正规的校徽,用 Windows 的画图工具打开,找出点的坐标然后用 数学方法变换的。
return true; else
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
SpanLeft = new CPoint2[nTotalScanLine];//跨度左边数组
SpanRight = new CPoint2[nTotalScanLine];//跨度右边数组
//判断三角形与P0P1边的位置关系,0-1-2为右手系
int nDeltz = (point1.x - point0.x) * (point2.y - point1.y) - (point1.y - point0.y) * (point2.x - point1.x);//点矢量叉积的z坐标
void CTriangle::Draw(CDC* pDC)//画出来一个三角形
{
pDC->MoveTo(point0.x,point0.y);
pDC->LineTo(point1.x,point1.y);
pDC->LineTo(point2.x,point2.y);
pDC->LineTo(point0.x,point0.y);
Arrow=FALSE;
Flag=TRUE;
Number=0;
MState=FALSE;
if(FALSE==Attach)
{
CClientDC dc(this);
Picture.CreateCompatibleDC(&dc);
MessageBox("请使用鼠标在屏幕上绘制多边形","提示", MB_ICONINFORMATION);
BOOL bInterChange = FALSE;//bInterChange为假,主位移方向为x方向
int e, s1, s2, temp;
s1 = (PEnd.x > PStart.x) ? 1 :((PEnd.x < PStart.x) ? -1 : 0);
s2 = (PEnd.y > PStart.y) ? 1 :((PEnd.y < PStart.y) ? -1 : 0);
}
}
Invalidate(FALSE);
CView::OnMouseMove(nFlags, point);
}
void CTestView::OnRButtonDown(UINT nFlags, CPoint point)//右键按下函数
{
// TODO: Add your message handler code here and/or call default
课程名称
班级
实验日期
姓 名
学号
实验成绩
实验名称
交互式绘制多边形
实 验 目 的
利用有效边表填充算法,编程实现多边形的填充。
实
验
环
境
VisualStudio2010
实
验
内
容
基本要求:
1. 了解有效边表和边表的数据结构;
2. 掌握边界像素的处理原则;
3. 掌握动态链表排序算法;
4. 使用鼠标绘制多边形,右键实现多边形的填充;
FColor=ccd.GetColor();
CPoint BPoint,EPoint;//边的起点和终点
long MaxX=p[0].x;//多边形的x坐标最大值
for(long Num=0;Num<Number;Num++)//求多边形的最大x值
{
BPoint.x=p[Num].x;
EPoint.x=p[(Num+1)%Number].x;
{
// TODO: Add your command handler code here
COLORREF FColor;//填充颜色
CColorDialog ccd(RGB(0,0,255));
if(ccd.DoModal()==IDOK)
{
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
}
void CTriangle::GouraudShader(CDC* pDC)
{
SortVertex();//point0点为y坐标最小的点,point1点为y坐标最大的点,point2点的y坐标位于二者之间。如果y值相同,取x最小的点
//定义三角形覆盖的扫描线条数
int nTotalScanLine = point1.y - point0.y + 1;
{
int n = y - point0.y;
for(int x = SpanLeft[n].x; x < SpanRight[n].x; x++)//左闭右开
{
clr = LinearInterp(x, SpanLeft[n].x, SpanRight[n].x, SpanLeft[n].c, SpanRight[n].c);
pDC->SetPixelV(x, y, RGB(clr.red * 255, clr.green * 255, clr.blue * 255));
}
}
if(SpanLeft)
{
delete []SpanLeft;
SpanLeft = NULL;
}
if(SpanRight)
{
delete []SpanRight;
EPoint.x=p[(Num+1)%Number].x,EPoint.y=p[(Num+1)%Number].y;
if(BPoint.y>EPoint.y)//确保起点的y值小于终点的y值
{
CPoint t;//临时对象
t=BPoint;
BPoint=EPoint;
EPoint=t;
}
double k=double(BPoint.x-EPoint.x)/(BPoint.y-EPoint.y);//计算1/k
for(long y=BPoint.y;y<EPoint.y;y++)//边缘填充算法
{
long x=ROUND(double(BPoint.x)+(double(y)-double(BPoint.y))*k);//处理一条边上各个点的x起始坐标
for(;x<MaxX;x++)
{
if(Picture.GetPixel(x,y)==FColor)
if(nDeltz > 0)//三角形位于P0P1边的左侧
{
nIndex = 0;
DDA(point0, point2, TRUE);
DDA(point2, point1, TRUE);
nIndex = 0;
DDA(point0, point1, FALSE);
}
else//三角形位于P0P1边的右侧
{
// TODO: Add your message handler code here and/or call default
if(Arrow)
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
else
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_CROSS));
SpanRight = NULL;
}
//}
}
void CTriangle::DDA(CPoint2 PStart, CPoint2 PEnd, BOOL bFeature)
{
CRGBA crColor = PStart.c;
int dx = abs(PEnd.x - PStart.x);
int dy = abs(PEnd.y - PStart.y);
实验拓展:绘制颜色渐变的三角形和四边形。
实
验
步
骤
问题分析和算法描述:
有效边表填充算法通过维护边表和有效边表,避开了扫描线与多边形所有边求交的复杂运算。填充原理是按照扫描线从小到大的移动顺序,计算当前扫描线与有效边的交点,然后把这些交点按x值递增的顺序进行排序、配对,以确定填充区间,最后用指定颜色填充区间内的所有像素,即完成填充工作。
if(Flag==TRUE)
{பைடு நூலகம்
if(Number<50)
{
LBDown=TRUE;
p[Number]=point;
if(!Number)
{
Number++;
}
Number++;
}
}
CView::OnLButtonDown(nFlags, point);
}
void CTestView::OnMouseMove(UINT nFlags, CPoint point)//鼠标移动函数
Arrow=TRUE;
LBDown=FALSE;
Flag=FALSE;
MState=TRUE;
CTestView::OnMENUFillPolygon();
CView::OnRButtonDown(nFlags, point);
}
(2)填充函数
void CTestView::OnMENUFillPolygon()//填充菜单操作函数
if(pStatus)
{
Str.Format("%d,%d",point.x,point.y);
pStatus->SetPaneText(2,Str);//状态栏显示鼠标光标位置值
}
if(LBDown)
{
p[Number-1]=point;
if(nFlags==MK_SHIFT)//约束:测试按下了Shift键