计算机图形学算法
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
x1=x+1。.y1=y+1/m
wk.baidu.com
• 重复操作
DDA算法程序
• #include<graphics.h>
• • • • • • • • • •
#include<stdlib.h> #include<stdio.h> #include<conio.h> #include<math.h> void dda_line(int xa,int ya,int xb,int yb,int c) { float delta_x,delta_y,x,y; int dx,dy,steps,k; dx=xb-xa; dy=yb-ya;
• • • • • • • • • • •
} void main() { int a,b,c,d,e; /* request auto detection */ int gdriver = DETECT, gmode, errorcode; char msg[80]; /* initialize graphics and local variables */ initgraph(&gdriver, &gmode, ""); /* read result of initialization */ errorcode = graphresult();
计算机图形学算法基础作业
• DDA直线生成法 • 中点画直线法 • Bresenham生成直线 • Bresenham画圆
DDA直线生成法
• DDA算法基本原理 • DDA是数字微分分析式(Digital Differential
Analyzer)的缩写。设直线之起点为,终点 为,则斜率为: • 直线中的每一点坐标都可以由前一点坐标 变化一个增量而得到,即表示为递归式: • 并有关系:
Bresenham生成直线
• Bresenham算法基本原理 • 本算法由Bresenham在1965年提出。设直线从起点到终点。
• • • •
直线可表示为方程。其中 我们讨论先将直线方向限于1a象限(图1.1)在这种情况 下,当直线光栅化时,x每次都增加1个单元,即 。而y的 相应增加应当小于1。为了光栅化,只可能选择如图1.2两 种位置之一。 图1.2 的位置选择 图1.2中 的位置选择 或者 选择的原则是看精确值与及的距离d1及d2的大小而定。计 算式为:
中点画直线法
• 下面讨论中点画线法的实现。过点、的直线段L的
方程式为,其中,,要判断中点M在Q点的上方还 是下方,只要把M代入,并判断它的符号即可。 为此,我们构造判别式: 当时,M在L(Q点)下方,取为下一个象素; 当时,M在L(Q点)上方,取为下一个象素; 当时,选或均可,约定取为下一个象素。
Bresenham生成直线
• • • • • •
1、画点(x1, y2); 计算误差初值P1=2dy-dx; i=1; 2、求直线的下一点位置: xi+1=xi+1; if Pi>0 则yi+1=yi+1; 否则yi+1=yi; 3、画点(xi+1, yi-1);
Bresenham生成直线
• • • • • •
Bresenham画圆
Bresenham画圆算法程序
• #include <graphics.h>
• #include <stdio.h> • #include <conio.h> • #include<math.h> • main()
Bresenham画圆算法程序
• • •
中点画直线法
• 注意到是的线性函数,可采用增量计算,提高运
• •
•
算效率。 若当前象素处于情况,则取正右方象素,要判下一 个象素位置,应计算,增量为a。 若时,则取右上方象素。要判断再下一象素, 则要计算,增量为。画线从开始,的初值,因, 所以。 由于我们使用的只是的符号,而且的增量都是 整数,只是初始值包含小数。因此,我们可以用 代替来摆脱小数,写出仅包含整数运算的算法程 序。
int a,b,c,d,e; /* request auto detection */ int gdriver = DETECT, gmode, errorcode; char msg[80]; /* initialize graphics and local variables */ initgraph(&gdriver, &gmode, ""); /* read result of initialization */ errorcode = graphresult(); if (errorcode != grOk) {
DDA算法程序
• • • • • • • • • • • •
putpixel(x,y,c); } } void main() { int a,b,c,d,e; int gdriver=DETECT,gmode,errorcode; char msg[80]; initgraph(&gdriver,&gmode,""); errorcode=graphresult(); if (errorcode != gr0k) {
DDA算法程序
• • • • • • • • • • • •
if(abs(dx)>abs(dy)) steps=abs(dx); else steps=abs(dy); delta_x=(float)dx/(float)steps; delta_y=(float)dy/(float)steps; x=xa; y=ya; putpixel(x,y,c); for(k=1;k<=steps;k++) { x+=delta_x; y+=delta_y;
Bresenham生成直线程序
• if (errorcode != grOk) • { • printf("Graphics error: %s\n", • • • • • • • • •
grapherrormsg(errorcode)); printf("Press any key to halt:"); getch(); exit(1); } printf("input two point and the color:\n"); scanf("%d,%d,%d,%d,%d",&a,&b,&c,&d,&e); Bresenhamline(a,b,c,d,e); getch(); }
算法流程
Bresenham生成直线程序
• • • • • • • • • • •
include <graphics.h> #include <stdlib.h> #include <stdio.h> #include <conio.h> void Bresenhamline(int x0,int y0,int x1,int y1,int color) { int dx=x1-x0; int dy=y1-y0; int dx2=dx<<1; int dy2=dy<<1; int e=-dx;
DDA算法程序
• • • • • • • • • •
printf("Graphics error:%s\n",grapherrormsg(errorcode)); printf("press any key to halt:"); getch(); exit(1); } printf("print two point and color\n"); scanf("%d,%d,%d,%d,%d",&a,&b,&c,&d,&e); dda_line(a,b,c,d,e); getch(); }
Bresenham生成直线
• 如果,则,否则。因此算法的关键在于简便地求出的符号。
• • • • •
将式(1.2.1)、(1.2.2)、(1.2.3)代入,得 用乘等式两边,并以代入上述等式,得 是我们用以判断符号的误差。由于在1a象限,总大于0, 所以仍旧可以用作判断符号的误差。为: 误差的初值P1,可将x1, y1,和b代入式(2.1.4)中的而 得到: 1.3.2 Bresenham算法实现步骤 综述上面1.3.1的推导,第1a象限内的直线Bresenham算法 思想如下:
各种算法比较
• DDA算法的优点是:绘制实数直线效果好,误差小;缺点 •
• • • • •
是:实现较复杂,不利于硬件实现。因为该算法涉及到实 数乘除法运算,y与k必须用浮点数表示,而且每一步都要 对y四舍五入后取整。 中点画线算法优点是:只有整数运算,不含乘除法;可用 硬件实现。 Bresenham算法的优点是: 1、不必计算直线之斜率,因此不做除法; 2、不用浮点数,只用整数; 3、只做整数加减法和乘2运算,而乘2运算可以用硬件移 位实现。 4、Bresenham算法速度很快,并适于用硬件实现。
Bresenham生成直线程序
• int x=x0; • int y=y0; • for(x=0;x<=x1;x++) • {putpixel(x,y,color); • e=e+dy2; • if(e>0) • { • y++; • e=e-dx2; • } • }
Bresenham生成直线程序
中点画直线程序
• • • • • • • • • •
while(x<x1) {if(d<0) {x++;y++; d+=d2;} else {x++; d+=d1;} putpixel(x,y,color); } } void main() {
中点画直线程序
• • • • • • • • • •
中点画直线程序
•
• • • • • • • • •
•
printf("Graphics error: %s\n", grapherrormsg(errorcode)); printf("Press any key to halt:"); getch(); exit(1); } printf("print two point and color\n"); scanf("%d,%d,%d,%d,%d",&a,&b,&c,&d,&e); MidpointLine(a,b,c,d,e); getch(); }
DDA直线生成法
• 递归式的初值为直线的起点,这样,就可以用加
• •
法来生成一条直线。 1.1.2 DDA算法实现步骤 具体方法是:
• 按照直线从到的方向不同,分为8个象限(见图
1)。对于方向在第1a象限内的直线而言,。对于 方向在第1b象限内的直线而言,取值各不相同。
算法流程
• 初始化 • 判断dx与dy中哪个较大当|dx|>|dy|时
4、求下一个误差Pi+1; if Pi>0 则Pi+1=Pi+2dy-2dx; 否则Pi+1=Pi+2dy; 5、i=i+1; if i<dx+1则转2;否则end。 1.3.3 Bresenham算法程序(或伪程序)描述 由上述算法思想编制的程序见附录3。这个程序适用于 所有8个方向的直线(图1.1)的生成。程序用色彩C画出 一条端点为和的直线。其中变量的含义是:P是误差; const1和const2,是误差的逐点变化量;inc是y的单位递 变量,值为1或-1;tmp是用作象限变换时的临时变量。程 序以判断为分支,并分别将2a,3a象限的直线和3b,4b象限 的直线变换到1a,4a和2b,1b方向去,以求得程序处理的简 洁。
程序流程
• 初始化。 • 用颜色color画像素 • 判断x2是否大于x,如果大于则结束。否则
进行下一步 • 判断d是否小于0如果小于则进行x=x+1, y=y+1。d=d+d1,否则执行x=x+1, d=d+d2 转入第二步
中点画直线程序
• • • • • • • • • •
#include <graphics.h> #include <stdlib.h> #include <stdio.h> #include <conio.h> void MidpointLine(int x0,int y0,int x1,int y1,int color) {int a,b,d1,d2,d,x,y; a=y0-y1;b=x1-x0;d=2*a+b; d1=2*a;d2=2*(a+b); x=x0;y=y0; putpixel(x,y,color);
wk.baidu.com
• 重复操作
DDA算法程序
• #include<graphics.h>
• • • • • • • • • •
#include<stdlib.h> #include<stdio.h> #include<conio.h> #include<math.h> void dda_line(int xa,int ya,int xb,int yb,int c) { float delta_x,delta_y,x,y; int dx,dy,steps,k; dx=xb-xa; dy=yb-ya;
• • • • • • • • • • •
} void main() { int a,b,c,d,e; /* request auto detection */ int gdriver = DETECT, gmode, errorcode; char msg[80]; /* initialize graphics and local variables */ initgraph(&gdriver, &gmode, ""); /* read result of initialization */ errorcode = graphresult();
计算机图形学算法基础作业
• DDA直线生成法 • 中点画直线法 • Bresenham生成直线 • Bresenham画圆
DDA直线生成法
• DDA算法基本原理 • DDA是数字微分分析式(Digital Differential
Analyzer)的缩写。设直线之起点为,终点 为,则斜率为: • 直线中的每一点坐标都可以由前一点坐标 变化一个增量而得到,即表示为递归式: • 并有关系:
Bresenham生成直线
• Bresenham算法基本原理 • 本算法由Bresenham在1965年提出。设直线从起点到终点。
• • • •
直线可表示为方程。其中 我们讨论先将直线方向限于1a象限(图1.1)在这种情况 下,当直线光栅化时,x每次都增加1个单元,即 。而y的 相应增加应当小于1。为了光栅化,只可能选择如图1.2两 种位置之一。 图1.2 的位置选择 图1.2中 的位置选择 或者 选择的原则是看精确值与及的距离d1及d2的大小而定。计 算式为:
中点画直线法
• 下面讨论中点画线法的实现。过点、的直线段L的
方程式为,其中,,要判断中点M在Q点的上方还 是下方,只要把M代入,并判断它的符号即可。 为此,我们构造判别式: 当时,M在L(Q点)下方,取为下一个象素; 当时,M在L(Q点)上方,取为下一个象素; 当时,选或均可,约定取为下一个象素。
Bresenham生成直线
• • • • • •
1、画点(x1, y2); 计算误差初值P1=2dy-dx; i=1; 2、求直线的下一点位置: xi+1=xi+1; if Pi>0 则yi+1=yi+1; 否则yi+1=yi; 3、画点(xi+1, yi-1);
Bresenham生成直线
• • • • • •
Bresenham画圆
Bresenham画圆算法程序
• #include <graphics.h>
• #include <stdio.h> • #include <conio.h> • #include<math.h> • main()
Bresenham画圆算法程序
• • •
中点画直线法
• 注意到是的线性函数,可采用增量计算,提高运
• •
•
算效率。 若当前象素处于情况,则取正右方象素,要判下一 个象素位置,应计算,增量为a。 若时,则取右上方象素。要判断再下一象素, 则要计算,增量为。画线从开始,的初值,因, 所以。 由于我们使用的只是的符号,而且的增量都是 整数,只是初始值包含小数。因此,我们可以用 代替来摆脱小数,写出仅包含整数运算的算法程 序。
int a,b,c,d,e; /* request auto detection */ int gdriver = DETECT, gmode, errorcode; char msg[80]; /* initialize graphics and local variables */ initgraph(&gdriver, &gmode, ""); /* read result of initialization */ errorcode = graphresult(); if (errorcode != grOk) {
DDA算法程序
• • • • • • • • • • • •
putpixel(x,y,c); } } void main() { int a,b,c,d,e; int gdriver=DETECT,gmode,errorcode; char msg[80]; initgraph(&gdriver,&gmode,""); errorcode=graphresult(); if (errorcode != gr0k) {
DDA算法程序
• • • • • • • • • • • •
if(abs(dx)>abs(dy)) steps=abs(dx); else steps=abs(dy); delta_x=(float)dx/(float)steps; delta_y=(float)dy/(float)steps; x=xa; y=ya; putpixel(x,y,c); for(k=1;k<=steps;k++) { x+=delta_x; y+=delta_y;
Bresenham生成直线程序
• if (errorcode != grOk) • { • printf("Graphics error: %s\n", • • • • • • • • •
grapherrormsg(errorcode)); printf("Press any key to halt:"); getch(); exit(1); } printf("input two point and the color:\n"); scanf("%d,%d,%d,%d,%d",&a,&b,&c,&d,&e); Bresenhamline(a,b,c,d,e); getch(); }
算法流程
Bresenham生成直线程序
• • • • • • • • • • •
include <graphics.h> #include <stdlib.h> #include <stdio.h> #include <conio.h> void Bresenhamline(int x0,int y0,int x1,int y1,int color) { int dx=x1-x0; int dy=y1-y0; int dx2=dx<<1; int dy2=dy<<1; int e=-dx;
DDA算法程序
• • • • • • • • • •
printf("Graphics error:%s\n",grapherrormsg(errorcode)); printf("press any key to halt:"); getch(); exit(1); } printf("print two point and color\n"); scanf("%d,%d,%d,%d,%d",&a,&b,&c,&d,&e); dda_line(a,b,c,d,e); getch(); }
Bresenham生成直线
• 如果,则,否则。因此算法的关键在于简便地求出的符号。
• • • • •
将式(1.2.1)、(1.2.2)、(1.2.3)代入,得 用乘等式两边,并以代入上述等式,得 是我们用以判断符号的误差。由于在1a象限,总大于0, 所以仍旧可以用作判断符号的误差。为: 误差的初值P1,可将x1, y1,和b代入式(2.1.4)中的而 得到: 1.3.2 Bresenham算法实现步骤 综述上面1.3.1的推导,第1a象限内的直线Bresenham算法 思想如下:
各种算法比较
• DDA算法的优点是:绘制实数直线效果好,误差小;缺点 •
• • • • •
是:实现较复杂,不利于硬件实现。因为该算法涉及到实 数乘除法运算,y与k必须用浮点数表示,而且每一步都要 对y四舍五入后取整。 中点画线算法优点是:只有整数运算,不含乘除法;可用 硬件实现。 Bresenham算法的优点是: 1、不必计算直线之斜率,因此不做除法; 2、不用浮点数,只用整数; 3、只做整数加减法和乘2运算,而乘2运算可以用硬件移 位实现。 4、Bresenham算法速度很快,并适于用硬件实现。
Bresenham生成直线程序
• int x=x0; • int y=y0; • for(x=0;x<=x1;x++) • {putpixel(x,y,color); • e=e+dy2; • if(e>0) • { • y++; • e=e-dx2; • } • }
Bresenham生成直线程序
中点画直线程序
• • • • • • • • • •
while(x<x1) {if(d<0) {x++;y++; d+=d2;} else {x++; d+=d1;} putpixel(x,y,color); } } void main() {
中点画直线程序
• • • • • • • • • •
中点画直线程序
•
• • • • • • • • •
•
printf("Graphics error: %s\n", grapherrormsg(errorcode)); printf("Press any key to halt:"); getch(); exit(1); } printf("print two point and color\n"); scanf("%d,%d,%d,%d,%d",&a,&b,&c,&d,&e); MidpointLine(a,b,c,d,e); getch(); }
DDA直线生成法
• 递归式的初值为直线的起点,这样,就可以用加
• •
法来生成一条直线。 1.1.2 DDA算法实现步骤 具体方法是:
• 按照直线从到的方向不同,分为8个象限(见图
1)。对于方向在第1a象限内的直线而言,。对于 方向在第1b象限内的直线而言,取值各不相同。
算法流程
• 初始化 • 判断dx与dy中哪个较大当|dx|>|dy|时
4、求下一个误差Pi+1; if Pi>0 则Pi+1=Pi+2dy-2dx; 否则Pi+1=Pi+2dy; 5、i=i+1; if i<dx+1则转2;否则end。 1.3.3 Bresenham算法程序(或伪程序)描述 由上述算法思想编制的程序见附录3。这个程序适用于 所有8个方向的直线(图1.1)的生成。程序用色彩C画出 一条端点为和的直线。其中变量的含义是:P是误差; const1和const2,是误差的逐点变化量;inc是y的单位递 变量,值为1或-1;tmp是用作象限变换时的临时变量。程 序以判断为分支,并分别将2a,3a象限的直线和3b,4b象限 的直线变换到1a,4a和2b,1b方向去,以求得程序处理的简 洁。
程序流程
• 初始化。 • 用颜色color画像素 • 判断x2是否大于x,如果大于则结束。否则
进行下一步 • 判断d是否小于0如果小于则进行x=x+1, y=y+1。d=d+d1,否则执行x=x+1, d=d+d2 转入第二步
中点画直线程序
• • • • • • • • • •
#include <graphics.h> #include <stdlib.h> #include <stdio.h> #include <conio.h> void MidpointLine(int x0,int y0,int x1,int y1,int color) {int a,b,d1,d2,d,x,y; a=y0-y1;b=x1-x0;d=2*a+b; d1=2*a;d2=2*(a+b); x=x0;y=y0; putpixel(x,y,color);