当前位置:文档之家› Bresenham画线

Bresenham画线

Bresenham画线
Bresenham画线

一、实验目标

本次实验目标主要是实现绘制各种情况直线的Bresenham 算法。

二、实验内容

本次实验要解决的问题主要是Bresenham 画线法在各个方向的画线的问题。 算法原理简述:过各行各列象素中心构造一组虚拟网格线。按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后根据误差项的符号确定该列象素中与此交点最近的象素。

设直线方程为: 其中k=dy/dx 。 因为直线的起始点在象素中心,所以误差项d 的初值d0=0。x 下标每增加1,d 的值相应递增直线的斜率值k ,即d =d +k 。一旦d>=1,就把它减去1,这样保证d 在0、1之间。当d>=0.5时,最接近于当前象素的右上方象素( )而当d<0.5时,更接近于右方象素( )。 为方便计算,令e =d-0.5,e 的初值为-0.5,增量为k 。

当e>=0时,取当前象素(xi ,yi )的右上方象素( );

而当e<0时,更接近于右方象素( )。

可以改用整数以避免除法。

三、实验步骤

一、打开cgdemoMFC 工程

k

y x x k y y i i i i i +=-+=++)(1111,++i i y x i i y x ,1+11,++i i y x i i y x ,1+d d d

d

1.打开Microsoft Visual Studio 2008

2.File-->Open-->cgdemo.sln

二、添加菜单

1.左侧视图栏中有三个视图:ClassView、ResourceView、FileView,点击ResourceView

2.展开cgdemo,展开Menu,双击IDR_MAINFRAME

3.在右侧窗口菜单栏中找到“基本图形生成”菜单项,在该菜单项中添加“Bresenham画线法”,在“Bresenham画线法”属性框中找到ID框填:ID_BRESENHAM。

三、创建、编辑函数

1.打开cgdemoView.h头文件,在cgdemoView类枚举类型成员变量m_drawstyle中添加LINE_BRESENHAM。

2.给菜单项“Bresenham画线法”添加命令消息响应函数OnBresenham()在该函数中添加以下程序代码。

void CcgdemoView::OnBresenham()

{

// TODO: Add your command handler code here

m_drawstyle=LINE_BRESENHAM;

Invalidate(true);

}

3.在鼠标左键按下消息响应函数中添加当m_drawstyle为LINE_BRESENHAM时的情况,代码如下所示。

void CcgdemoView::OnLButtonDown(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

switch(m_drawstyle)

{

case LINE_DDA:

case LINE_MIDPT:

case LINE_BRESENHAM:

}

4.在鼠标移动消息响应函数中添加m_drawstyle为LINE_BRESENHAM时的情况,代码如下所示。

void CcgdemoView::OnMouseMove(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

switch(m_drawstyle)

{

case LINE_DDA:

case LINE_MIDPT:

case LINE_BRESENHAM:

}

5.在cgdemoView.h头文件类中添加成员函数void LineBresenham(CDC* pDC, int x1,int y1,int x2, int y2,int color);在cgdemoView.cpp源文件中为其添加代码。

四、编译,运行。

四、实验遇到的问题及其解决方法(重点)

在Bresenham算法画直线程序的编写过程中在算法推导方面主要遇到的问

题是:坐标系之间的转换,判断dx,dy与0的关系,即判断点(x2,y2)与点(x1,y1)的方向位置关系。如下图所示,判断点(x2,y2)与点(x1,y1)位置关系,并在不同位置情况下考虑不同的情况编写代码。

在Bresenham算法画直线的算法推导过程通过算法的推导令e=2*dx*e’,其中e’=d-0.5。即增量可化简为e=e+2*dy,e=e-2*dx从而消除了浮点数运算,2*dx、2*dy我们可以事先计算。最终Bresenham算法只包含加减运算和整形运算。

通过上网查阅有关Bresenham画线算法的有关资料以及同学之间的相互讨论,最终解决了该问题。

在Bresenham算法画直线程序的编写过程中在编程方面主要遇到的问题是:编写Bresenham画直线算法过程中,在不同情况下的代码编写过程,不同情况下

通过判断e与0的大小关系判断下一个像素点的坐标。例如,当e大于0的情况下判断是y1自增或自减运算还是x1自增或自减运算。

通过查阅有关资料,列举例子以及和同学之间的讨论等,最终解决问题。

在Bresenham算法画直线程序的编写过程中在编译过程方面主要遇到的问题是:由于自己编写代码的疏忽,有的语句最后忘记加“;”,括号的不匹配“{”导致编译时出现错误。

通过错误提示,修改代码,编译成功,运行出正确的结果。

五、实验结论和收获

通过做Bresenham画线算法,让我了解到了Bresenham算法实现的具体过程,对Brensenham算法生成线的过程和特点也有个更进一步的学习和掌握。更加对MFC单文档工程更加熟悉,学会了对菜单项的添加以及对添加的菜单项添加消息命令函数,左键按下以及鼠标移动消息响应函数等等。

c语言经典算法

C语言的学习要从基础,100个经典的算法 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? ________________________________________________________________ 程序分析:兔子的规律为数列1,1,2,3,5,8,13,21.... __________________________________________________________________ 程序源代码: main() { long f1,f2; int i; f1=f2=1; for(i=1;i<=20;i++) { printf("%12ld %12ld",f1,f2); if(i%2==0) printf("\n");/*控制输出,每行四个*/ f1=f1+f2;/*前两个月加起来赋值给第三个月*/ f2=f1+f2;/*前两个月加起来赋值给第三个月*/ } } 上题还可用一维数组处理,you try! 题目:判断101-200之间有多少个素数,并输出所有素数。 _________________________________________________________________ 程序分析:判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除,则表明此数不是素数,反之是素数。 ___________________________________________________________________ 程序源代码: #include "math.h" main() { int m,i,k,h=0,leap=1; printf("\n"); for(m=101;m<=200;m++) { k=sqrt(m+1); for(i=2;i<=k;i++) if(m%i==0) {leap=0;break;} if(leap) {printf("%-4d",m);h++; if(h%10==0) printf("\n"); } leap=1; } printf("\nThe total is %d",h); } 题目:打印出所有的“水仙花数”,所谓“水仙花数”是指一个三位数,其各位数字立方和等于该数本身。例如:153是一个“水仙花数”,因为153=1的三次方+5的三次方+3的三次方。 __________________________________________________________________ 程序分析:利用for循环控制100-999个数,每个数分解出个位,十位,百位。 ___________________________________________________________________ 程序源代码:

C语言经典算法100例题目

看懂一个程序,分三步:1、流程;2、每个语句的功能;3、试数; 小程序:1、尝试编程去解决他;2、看答案;3、修改程序,不同的输出结果; 4、照答案去敲; 5、调试错误; 6、不看答案,自己把答案敲出来; 7、实在不会就背会。。。。。周而复始,反复的敲。。。。。 【程序1】 题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? ============================================================== 【程序2】 题目:企业发放的奖金根据利润提成。利润(I)低于或等于10万元时,奖金可提10%;利润高 于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可可提 成7.5%;20万到40万之间时,高于20万元的部分,可提成5%;40万到60万之间时高于 40万元的部分,可提成3%;60万到100万之间时,高于60万元的部分,可提成1.5%,高于 100万元时,超过100万元的部分按1%提成,从键盘输入当月利润I,求应发放奖金总数? ============================================================== 【程序3】 题目:一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?============================================================== 【程序4】 题目:输入某年某月某日,判断这一天是这一年的第几天? ============================================================== 【程序5】 题目:输入三个整数x,y,z,请把这三个数由小到大输出。 ============================================================== 【程序6】 题目:用*号输出字母C的图案。 ============================================================== 【程序7】 题目:输出特殊图案,请在c环境中运行,看一看,Very Beautiful! ============================================================== 【程序8】 题目:输出9*9口诀。 ============================================================== 【程序9】 题目:要求输出国际象棋棋盘。 ============================================================== 【程序10】 题目:打印楼梯,同时在楼梯上方打印两个笑脸。 -------------------------------------------------------------------------------- 【程序11】 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月 后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? ==============================================================

C语言经典算法100例(1---30)

2008-02-18 18:48 【程序1】 题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 1.程序分析:可填在百位、十位、个位的数字都是1、2、3、4。组成所有的排列后再去 掉不满足条件的排列。 2.程序源代码: main() { int i,j,k; printf("\n"); for(i=1;i<5;i++) /*以下为三重循环*/ for(j=1;j<5;j++) for (k=1;k<5;k++) { if (i!=k&&i!=j&&j!=k) /*确保i、j、k三位互不相同*/ printf("%d,%d,%d\n",i,j,k); } } ============================================================== 【程序2】 题目:企业发放的奖金根据利润提成。利润(I)低于或等于10万元时,奖金可提10%;利润高 于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可可提 成7.5%;20万到40万之间时,高于20万元的部分,可提成5%;40万到60万之间时高于 40万元的部分,可提成3%;60万到100万之间时,高于60万元的部分,可提成1.5%,高于 100万元时,超过100万元的部分按1%提成,从键盘输入当月利润I,求应发放奖金总数? 1.程序分析:请利用数轴来分界,定位。注意定义时需把奖金定义成长整型。 2.程序源代码: main() { long int i; int bonus1,bonus2,bonus4,bonus6,bonus10,bonus; scanf("%ld",&i); bonus1=100000*0.1;bonus2=bonus1+100000*0.75; bonus4=bonus2+200000*0.5; bonus6=bonus4+200000*0.3; bonus10=bonus6+400000*0.15; if(i<=100000)

计算机图形学画圆实验报告

洛阳理工学院实验报告用纸

(2)画理想圆流程图如图-1: 图-1:画理想圆流程图 (3)中点画圆法 图-2 中点画圆法当前象素与下一象素的候选者

数,将乘法运算改成加法运算,即仅用整数实现中点画圆法。 (4)Bresenham画圆法 Bresenham画线法与中点画线法相似,,它通过每列象素中确定与理想直线最近的象素来进行直线的扫描的转换的。通过各行,各列的象素中心构造一组虚拟网格线的交点,然后确定该列象素中与此交点最近的的象素。该算法的巧妙之处在于可以采用增量计算,使得对于每一列,只要检查一个误差项的符号,就可以确定该列的所求对象。 假设x列的象素已确定,其行下标为y。那么下一个象素的列坐标必为x+1。而行坐标要么不变,要么递增1。是否递增1取决于如图所示的误差项d的值。因为直线的起始点在象素中心,所以误差项d的初始值为0。X下标每增加1,d的值相应递增直线的斜率值,即d=d+k(k=y/x为直线斜率)。一旦d>=1时,就把它减去,这样保证d始终在0、1之间。当d>0.5时,直线与x+1垂直网络线交点最接近于当前象素(x,y)的右上方象素(x+1,y+1);而当d<0.5时,更接近于象素(x+1,y),当d=0。5时,与上述二象素一样接近,约定取(x+1,y+1)。令e=d-0。5。则当e>=0时,下一象素的y下标增加1,而当e〈0时,下一象素的y下标不增。E的初始值为-0.5. (二)实验设计 画填充点流程图,如图-3: 图-3:圆的像素填充过程NS图 画理想圆,记录圆心坐标,计算半径大小,并记录 是否开始填充 否 是 初始化计数器、标志变量,设置最大计数值 调用Bresenha m画圆算法 否 是 填充标记是否为真 (While)计数变量小于最大计数值 循环变量temp + 1 填充计算出来的temp个坐 标点 计算需要填充坐标数组的 前temp个坐标

案例2-直线中点Bresenham算法

课程实验报告

步骤 为了规范颜色的处事,定义了CRGB类,重载了“+”,“-”、“*”、“\”、“+=”、“-=”、“*=”、“/=”运算符。成员函数Normalize()将颜色分量red,green,blue规范到[0,1]闭区间内。 RGB.h #pragma once class CRGB { public: CRGB(); CRGB(double, double, double); ~CRGB(); friend CRGB operator + (const CRGB&, const CRGB&); friend CRGB operator - (const CRGB&, const CRGB&); friend CRGB operator * (const CRGB&, const CRGB&); friend CRGB operator * (const CRGB&, double); friend CRGB operator * (double, const CRGB&); friend CRGB operator / (const CRGB&, double); friend CRGB operator += (const CRGB&, const CRGB&); friend CRGB operator -= (const CRGB&, const CRGB&); friend CRGB operator *= (const CRGB&, const CRGB&); friend CRGB operator /= (const CRGB&, double); void Normalize(); public: double red; double green; double blue; }; RGB.cpp #include"stdafx.h" #include"RGB.h" CRGB::CRGB() { red = 1.0; green = 1.0; blue = 1.0;

Bresenham的直线生成算法和整圆生成算法完整代码

以下是Bresenham的直线生成算法和整圆生成算法,已调试过,没有任何问题。Bresenham直线生成算法 #include "stdio.h" #include "graphics.h" Bresenham_line(x0,y0,x1,y1,color) int x0,y0,x1,y1,color; { int x,y,dx,dy, i; float k,e; dx=x1-x0;dy=y1-y0; k=(dy*1.0)/dx; e=-0.5; x=x0; y=y0; for (x=x0; x<=x1; x++) { putpixel(x,y,color); e=e+k; if(e>=0) { y++;e=e-1;} } } int main() { int x0,y0,x1,y1,c; int driver=DETECT,mode=0; initgraph(&driver,&mode,"c:\\tc"); setbkcolor(BLUE); setcolor(YELLOW); printf("input x0,y0,x1,y1,c"); scanf("%d%d%d%d%d",&x0,&y0,&x1,&y1,&c); Bresenham_line(x0,y0,x1,y1,c); getch(); closegraph(); } 当取e=2*dy-dx时,可以消除浮点和除法运算 #include "stdio.h" #include "graphics.h" Bresenham_line(x0,y0,x1,y1,color)

int x0,y0,x1,y1,color; { int x,y,dx,dy, i,e; float k; dx=x1-x0;dy=y1-y0; k=(dy*1.0)/dx; e=2*dy-dx; x=x0; y=y0; for (x=x0; x<=x1; x++) { putpixel(x,y,color); e=e+2*dy; if(e>=0) { y++;e=e-2*dx;} } } int main() { int x0,y0,x1,y1,c; int driver=DETECT,mode=0; initgraph(&driver,&mode,"c:\\tc"); setbkcolor(BLUE); setcolor(YELLOW); printf("input x0,y0,x1,y1,c"); scanf("%d%d%d%d%d",&x0,&y0,&x1,&y1,&c); Bresenham_line(x0,y0,x1,y1,c); getch(); closegraph(); }

实验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 CTestView 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_FILE static char THIS_FILE[] = __FILE__; #endif // CTestView IMPLEMENT_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 commands ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)

Bresenham算法

Course Page
Page 1 of 6
课程首页 > 第二章 二维图形的生成 > 2.1 直线的生成 > 2.1.2 生成直线的Bresenham算法
全部隐藏
2.1.2 生成直线的Bresenham算法
从上面介绍的DDA算法可以看到,由于在循环中涉及实型数据的加减运算,因此直线的生成速度较慢。 在生成直线的算法中,Bresenham算法是最有效的算法之一。Bresenham算法是一种基于误差判别式来生成直线的方法。 一、直线Bresenham算法描述: 它也是采用递推步进的办法,令每次最大变化方向的坐标步进一个象素,同时另一个方向的坐标依据误差判别式的符号来决定是否也要步进一 个象素。 我们首先讨论m=△ y/△x,当0≤m≤1且x1有两种Bresenham算法思想,它们各自从不同角度介绍了Bresenham算法思想,得出的误差判别式都是一样的。 二、直线Bresenham算法思想之一: 由于显示直线的象素点只能取整数值坐标,可以假设直线上第i个象素点坐标为(xi,yi),它是直线上点(xi,yi)的最佳近似,并且xi=xi(假设 m<1),如下图所示。那么,直线上下一个象素点的可能位置是(xi+1,yi)或(xi+1,yi+1)。
由图中可以知道,在x=xi+1处,直线上点的y值是y=m(xi+1)+b,该点离象素点(xi+1,yi)和象素点(xi+1,yi+1)的距离分别是d1和d2:
d1=y-yi=m(xi+1)+b-yi d2=(yi+1)-y=(yi+1)-m(xi+1)-b 这两个距离差是 d1-d2=2m(xi+1)-2yi+2b-1
(2-8) (2-9)
(2-10)
我们来分析公式(2-10): (1)当此值为正时,d1>d2,说明直线上理论点离(xi+1,yi+1)象素较近,下一个象素点应取(xi+1,yi+1)。 (2)当此值为负时,d1mhtml:file://C:\Documents and Settings\Administrator\桌面\Course Page.mht
2011-7-12

C语言经典算法大全

C语言经典算法大全 老掉牙 河内塔 费式数列 巴斯卡三角形 三色棋 老鼠走迷官(一) 老鼠走迷官(二) 骑士走棋盘 八个皇后 八枚银币 生命游戏 字串核对 双色、三色河内塔 背包问题(Knapsack Problem) 数、运算 蒙地卡罗法求PI Eratosthenes筛选求质数 超长整数运算(大数运算) 长PI 最大公因数、最小公倍数、因式分解 完美数 阿姆斯壮数 最大访客数 中序式转后序式(前序式) 后序式的运算 关于赌博 洗扑克牌(乱数排列) Craps赌博游戏 约瑟夫问题(Josephus Problem) 集合问题 排列组合 格雷码(Gray Code) 产生可能的集合

m元素集合的n个元素子集 数字拆解 排序 得分排行 选择、插入、气泡排序 Shell 排序法- 改良的插入排序Shaker 排序法- 改良的气泡排序Heap 排序法- 改良的选择排序快速排序法(一) 快速排序法(二) 快速排序法(三) 合并排序法 基数排序法 搜寻 循序搜寻法(使用卫兵) 二分搜寻法(搜寻原则的代表)插补搜寻法 费氏搜寻法 矩阵 稀疏矩阵 多维矩阵转一维矩阵 上三角、下三角、对称矩阵 奇数魔方阵 4N 魔方阵 2(2N+1) 魔方阵

1.河内之塔 说明河内之塔(Towers of Hanoi)是法国人M.Claus(Lucas)于1883年从泰国带至法国的,河内为越 战时北越的首都,即现在的胡志明市;1883年法国数学家Edouard Lucas曾提及这个故事,据说创世纪时Benares有一座波罗教塔,是由三支钻石棒(Pag)所支撑,开始时神在第一根棒上放置64个由上至下依由小至大排列的金盘(Disc),并命令僧侣将所有的金盘从第一根石棒移至第三根石棒,且搬运过程中遵守大盘子在小盘子之下的原则,若每日仅搬一个盘子,则当盘子全数搬运完毕之时,此塔将毁损,而也就是世界末日来临之时。 解法如果柱子标为ABC,要由A搬至C,在只有一个盘子时,就将它直接搬至C,当有两个盘 子,就将B当作辅助柱。如果盘数超过2个,将第三个以下的盘子遮起来,就很简单了,每次处理两个盘子,也就是:A->B、A ->C、B->C这三个步骤,而被遮住的部份,其实就是进入程式的递回处理。事实上,若有n个盘子,则移动完毕所需之次数为2^n - 1,所以当盘数为64时,则所需次数为:264- 1 = 18446744073709551615为5.05390248594782e+16年,也就是约5000世纪,如果对这数字没什幺概念,就假设每秒钟搬一个盘子好了,也要约5850亿年左右。 #include void hanoi(int n, char A, char B, char C) { if(n == 1) { printf("Move sheet %d from %c to %c\n", n, A, C); } else { hanoi(n-1, A, C, B); printf("Move sheet %d from %c to %c\n", n, A, C); hanoi(n-1, B, A, C); } } int main() { int n; printf("请输入盘数:"); scanf("%d", &n); hanoi(n, 'A', 'B', 'C'); return 0; }

DDA算法 中点画线算法 Bresenham算法

实验1直接绘制实验 (提示:#表示Project的编号,##表示Project题目) 学号姓名上交时间 1.问题描述 如何利用OpenGL实现直线光栅化的DDA算法、中点画线算法和Bresenham算法2.算法描述 DDA算法:据直线公式y = kx + b来推导出来的,其关键之处在于如何设定单位步进,即一个方向的步进为单位步进,另一个方向的步进必然是小于1。 中点划线法:在画直线段的过程中,当前像素点为(xp ,yp ),下一个像素点有两种可选择点P1(xp +1,yp )或P2(xp +1,yp +1)。若M=(xp +1,yp +0.5)为P1与P2之中点,Q 为P理想直线与x=xp +1垂线的交点。当M在Q的下方,则P2应为下一个像素点; M在Q的上方,应取P1为下一个像素点。 Bresenham算法:过各行、各列像素中心构造一组虚拟网格线,按直线从起点到终点的顺序计算直线各垂直网格线的交点,然后确定该列像素中与此交点最近 的像素。 实验结果 成功运行三个算法,并且能转换出通用Bresenham算法。 3.分析与评论 (分析每个算法的运行时间,对你的本实验的工作进行评论,同时也可以对老师提出建议。) 附录: Source Code(in C)

#include //需要正确安装GLUT,安装方法如预备知识中所述void myDisplay(void) { glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); glColor3f (1.0f, 1.0f, 1.0f); glRectf(-0.5f, -0.5f, 0.5f, 0.5f); glBegin (GL_TRIANGLES); glColor3f (1.0f, 0.0f, 0.0f); glVertex2f (0.0f, 1.0f); glColor3f (0.0f, 1.0f, 0.0f); glVertex2f (0.8f, -0.5f); glColor3f (0.0f, 0.0f, 1.0f); glVertex2f (-0.8f, -0.5f); glEnd (); glColor3f(1,0,0); glBegin(GL_LINE_LOOP); glVertex2f (0.0f, 0.5f); glVertex2f (0.4f, -0.25f); glVertex2f (-0.4f, -0.25f); glEnd (); glPointSize(3); glBegin (GL_POINTS); glColor3f (1.0f, 0.0f, 0.0f); glVertex2f (-0.4f, -0.4f); glColor3f (0.0f, 1.0f, 0.0f); glVertex2f (0.0f, 0.0f); glColor3f (0.0f, 0.0f, 1.0f); glVertex2f (0.4f, 0.4f); glEnd (); glFlush(); } int main(intargc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);

C语言必背18个经典程序

C语言必背18个经典程序 (总10页) -CAL-FENGHAI.-(YICAI)-Company One1 -CAL-本页仅作为文档封面,使用请直接删除

C语言必背18个经典程序 1、/*输出9*9口诀。共9行9列,i控制行,j控制列。*/ #include "stdio.h" main() {int i,j,result; for (i=1;i<10;i++) { for(j=1;j<10;j++) { result=i*j; printf("%d*%d=%-3d",i,j,result);/*-3d表示左对齐,占3位*/ } printf("\n");/*每一行后换行*/ } system("pause"); } 2、/*古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 兔子的规律为数列1,1,2,3,5,8,13,21....*/ main() { long f1,f2; int i; f1=f2=1; for(i=1;i<=20;i++) { printf("%12ld %12ld",f1,f2); if(i%2==0) printf("\n");/*控制输出,每行四个*/ f1=f1+f2; /*前两个月加起来赋值给第三个月*/ f2=f1+f2; /*前两个月加起来赋值给第三个月*/ } } 3、/*判断101-200之间有多少个素数,并输出所有素数及素数的个数。 程序分析:判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除, 则表明此数不是素数,反之是素数。*/ #include "math.h" main() { int m,i,k,h=0,leap=1; printf("\n"); for(m=101;m<=200;m++) { k=sqrt(m); for(i=2;i<=k;i++)

C语言经典算法题目及答案

题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 1.程序分析:可填在百位、十位、个位的数字都是1、2、3、4。组成所有的排列后再去 掉不满足条件的排列。 2.程序源代码: main() { int i,j,k; printf("\n"); for(i=1;i<5;i++) /*以下为三重循环*/ for(j=1;j<5;j++) for (k=1;k<5;k++) { if (i!=k&&i!=j&&j!=k) printf("%d,%d,%d\n",i,j,k); } } ============================================================== 【程序2】 题目:企业发放的奖金根据利润提成。利润(I)低于或等于10万元时,奖金可提10%;利润高 于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可可提成7.5%;20万到40万之间时,高于20万元的部分,可提成5%;40万到60万之间时高于40万元的部分,可提成3%;60万到100万之间时,高于60万元的部分,可提成1.5%,高于 100万元时,超过100万元的部分按1%提成,从键盘输入当月利润I,求应发放奖金总数? 1.程序分析:请利用数轴来分界,定位。注意定义时需把奖金定义成长整型。 2.程序源代码: main() { long int i; int bonus1,bonus2,bonus4,bonus6,bonus10,bonus; scanf("%ld",&i); bonus1=100000*0.1;bonus2=bonus1+100000*0.75; bonus4=bonus2+200000*0.5; bonus6=bonus4+200000*0.3; bonus10=bonus6+400000*0.15; if(i<=100000) bonus=i*0.1; else if(i<=200000) bonus=bonus1+(i-100000)*0.075; else if(i<=400000) bonus=bonus2+(i-200000)*0.05; else if(i<=600000) bonus=bonus4+(i-400000)*0.03;

计算机图形学画圆算法源程序

#include void CirclePoint(int x, int y, int color, int m ) { putpixel(x+m, y+m, color); putpixel(y+m, x+m, color); putpixel(-y+m, x+m, color); putpixel(-x+m, y+m, color); putpixel(-x+m, -y+m, color); putpixel(-y+m, -x+m, color); putpixel(y+m, -x+m, color); putpixel(x+m, -y+m, color); } void MidBresenhamCircle(int r,int color, int m) { int x, y, d; x=0; y=r; d=1-r; while(x<=y) { CirclePoint(x, y, color, m); if(d<0) d+=2*x+3; else { d+=2*(x-y)+5; y--; } x++; } } void main() { int gdriver,gmode,a,b,c; gdriver=DETECT; initgraph(&gdriver,&gmode,"C:\\TC20\\BGI"); printf("qing shu ru\n"); scanf("%d,%d,%d",&a,&b,&c) setbkcolor(0); MidBresenhamCircle(a, b, c); getch(); closegraph(); }

计算机图形学 实验 数值微分(DDA)法、中点画线法、Bresenham算法

XXXXXXXX 大学(计算机图形学)实验报告 实验名称 数值微分(DDA )法、中点画线法、Bresenham 算法 实验时间 年 月 日 专 业 姓 名 学 号 预 习 操 作 座 位 号 教师签名 总 评 一、实验目的: 1.了解数值微分(DDA )法、中点画线法、Bresenham 算法的基本思想; 2.掌握数值微分(DDA )法、中点画线法、Bresenham 算法的基本步骤; 二、实验原理: 1.数值微分(DDA)法 已知过端点 的直线段L :y=kx+b,直线斜率为 从x 的左端点 开始,向x 右端点步进。步长=1(个象素),计算相应的y 坐标y=kx+b ;取象素点(x, round(y))作为当前点的坐标。 2.中点画线法 当前象素点为(x p , y p ) 。下一个象素点为P 1 或P 2 。 设M=(x p +1, y p +0.5),为p 1与p 2之中点,Q 为理想直线与x=x p +1垂线的交点。将Q 与 M 的y 坐标进行比较。 当M 在Q 的下方,则P 2 应为下一个象素点; 当M 在Q 的上方,应取P 1为下一点。 构造判别式:d=F(M)=F(x p +1,y p +0.5)=a(x p +1)+b(y p +0.5)+c ,其中a=y 0-y 1, b=x 1-x 0, c=x 0y 1-x 1y 0。 当d<0,M 在L(Q 点)下方,取右上方P 2为下一个象素; 当d>0,M 在L(Q 点)上方,取右方P 1为下一个象素; 当d=0,选P 1或P 2均可,约定取P 1为下一个象素; 但这样做,每一个象素的计算量是4个加法,两个乘法。 d 是x p , y p 的线性函数,因此可采用增量计算,提高运算效率。 若当前象素处于d ≥0情况,则取正右方象素P 1 (x p +1, y p), 要判下一个象素位置,应计算 d 1=F(x p +2, y p +0.5)=a(x p +2)+b(y p +0.5)=d+a ; 增量为a 。 若d<0时,则取右上方象素P 2 (x p +1, y p +1)。要判断再下一象素,则要计算 d 2= F(x p +2, y p +1.5)=a(x p +2)+b(y p +1.5)+c=d+a+b ;增量为a +b 。 3.Bresenham 算法 过各行各列象素中心构造一组虚拟网格线。按直线从起点到终点的顺序计算直线与各垂 ),(),,(111000y x P y x P 0101x x y y k --=0x

C语言经典算法题目及答案

盛年不重来,一日难再晨。及时宜自勉,岁月不待人。 题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 1.程序分析:可填在百位、十位、个位的数字都是1、2、3、4。组成所有的排列后再去 掉不满足条件的排列。 2.程序源代码: main() { int i,j,k; printf("\n"); for(i=1;i<5;i++) /*以下为三重循环*/ for(j=1;j<5;j++) for (k=1;k<5;k++) { if (i!=k&&i!=j&&j!=k) printf("%d,%d,%d\n",i,j,k); } } ============================================================== 【程序2】 题目:企业发放的奖金根据利润提成。利润(I)低于或等于10万元时,奖金可提10%;利润高 于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可可提成7.5%;20万到40万之间时,高于20万元的部分,可提成5%;40万到60万之间时高于40万元的部分,可提成3%;60万到100万之间时,高于60万元的部分,可提成1.5%,高于 100万元时,超过100万元的部分按1%提成,从键盘输入当月利润I,求应发放奖金总数? 1.程序分析:请利用数轴来分界,定位。注意定义时需把奖金定义成长整型。 2.程序源代码: main() { long int i; int bonus1,bonus2,bonus4,bonus6,bonus10,bonus; scanf("%ld",&i); bonus1=100000*0.1;bonus2=bonus1+100000*0.75; bonus4=bonus2+200000*0.5; bonus6=bonus4+200000*0.3; bonus10=bonus6+400000*0.15; if(i<=100000) bonus=i*0.1; else if(i<=200000) bonus=bonus1+(i-100000)*0.075; else if(i<=400000) bonus=bonus2+(i-200000)*0.05; else if(i<=600000)

Bresenham直线算法与画圆算法

Bresenham直线算法与画圆算法 文章分类:Java编程 计算机是如何画直线的?简单来说,如下图所示,真实的直线是连续的,但我们的计算机显示的精度有限,不可能真正显示连续的直线,于是我们用一系列离散化后的点(像素)来近似表现这条直线。 (上图来自于互联网络,《计算机图形学的概念与方法》柳朝阳,郑州大学数学系) 接下来的问题就是如何尽可能高效地找到这些离散的点,Bresenham直线算法就是一个非常不错的算法。 Bresenham直线算法是用来描绘由两点所决定的直线的算法,它会算出一条线段在 n 维光栅上最接近的点。这个算法只会用到较为快速的整数加法、减法和位元移位,常用于绘制电脑画面中的直线。是计算机图形学中最先发展出来的算法。 (引自wiki百科布雷森漢姆直線演算法) 这个算法的流程图如下:

可以看到,算法其实只考虑了斜率在 0 ~ 1 之间的直线,也就是与 x 轴夹角在 0 度到 45 度的直线。只要解决了这类直线的画法,其它角度的直线的绘制全部可以通过简单的坐标变换来实现。 下面是一个C语言实现版本。 Java代码 1.view sourceprint? 2. // 交换整数 a 、b 的值 3. 4.inline void swap_int(int *a, int *b) 5.{ 6. *a ^= *b; 7. *b ^= *a; 8. *a ^= *b;

9.} 10. 11.// Bresenham's line algorithm 12. 13.void draw_line(IMAGE *img, int x1, int y1, int x2, int y2, unsi gned long c) 14.{ 15. // 参数 c 为颜色值 16. int dx = abs(x2 - x1), 17. dy = abs(y2 - y1), 18. yy = 0; 19. 20. if(dx < dy) 21. { 22. yy = 1; 23. swap_int(&x1, &y1); 24. swap_int(&x2, &y2); 25. swap_int(&dx, &dy); 26. } 27. 28. int ix = (x2 - x1) > 0 ? 1 : -1, 29. iy = (y2 - y1) > 0 ? 1 : -1, 30. cx = x1, 31. cy = y1, 32. n2dy = dy * 2, 33. n2dydx = (dy - dx) * 2, 34. d = dy * 2 - dx; 35. 36.// 如果直线与 x 轴的夹角大于45度 37. if(yy) 38. { 39. while(cx != x2) 40. { 41. if(d < 0) 42. { 43. d += n2dy; 44. } 45. else 46. { 47. cy += iy; 48. d += n2dydx; 49. } 50. 51. putpixel(img, cy, cx, c);

bresenham画线算法详解

给定两个点起点P1(x1, y1), P2(x2, y2),如何画它们直连的直线呢,即是如何得到上图所示的蓝色的点。假设直线的斜率00,直线在第一象限,Bresenham算法的过程如下: 1.画起点(x1, y1). 2.准备画下一个点,X坐标加1,判断如果达到终点,则完成。否则找下一个点,由图可知要画的点要么为当前点的右邻接点,要么是当前点的右上邻接点。 2.1.如果线段ax+by+c=0与x=x1+1的交点y坐标大于(y+*y+1))/2则选右上那个点 2.2.否则选右下那个点。 3.画点 4.跳回第2步 5.结束 具体的算法如下,原理就是比较目标直线与x+1直线交点的纵坐标,哪个离交点近就去哪个void Bresenhamline(int x0, int y0, int x1, int y1, int color) { int x, y, dx, dy; float k, e; dx = x1 - x0; dy = y1 - y0; k = dy / dx; e = -0.5; x = x0; y = y0; for (x= x0;x < x1; x++) { drawpixel(x, y, color);//这个是画点子函数

e = e + k; if (e > 0) { y++; e = e - 1; } } } 上述Bresenham算法在计算直线斜率与误差项时用到小数与除法。可以改用整数以避免除法。等式两边同时乘以2*dx,得到2*e*dx = 2*e*dx + 2dy, 2*e*dx = 2*e*dx - 2*dx.由于算法中只用到误差项的符号,因此可作如下替换:2*e*dx.改进的Bresenham画线算法程序:将e统一乘以2*dx即变成了整数的Bresenhan算法了,^_^ void InterBresenhamline (int x0, int y0, int x1, int y1, int color) { int dx = x1 - x0; int dy = y1 - y0; int dx2 = dx << 1;//乘2 int dy2 = dy<< 1;//乘2 int e = -dx; int x = x0; int y = y0; for (x = x0; x < x1; x++) { drawpixel (x, y, color); e=e + dy2; if (e > 0) { y++; e = e - dx2; } } }

相关主题
文本预览
相关文档 最新文档