基本图元的生成算法
第4章 基本图元的生成
putpixel(xc+x,yc-y);
{ plotC(x,y,xc,yc); if(d<0)
putpixel(xc-x,yc+y); putpixel(xc-x,yc-y);
d+=4*x+6;
putpixel(xc+y,yc+x);
else {
putpixel(xc+y,yc-x);
d+=4*(x-y)+10;
d 1=F(xp+2, yp+1.5)=a(xp+2)+b(yp+1.5)+c=d+a+b
增量d1-d=a+b * d>=0时,应取正右方的P1。 接着判断再下一个像素的选取,则需计算:
d2=F(xp+2, yp+0.5)=a(xp+2)+b(yp+0.5)+c=d+a
增量d2-d=a * d的初值d0=F(x0+1,y0+0.5)=a(x0+1)+b(y0+0.5)+c
原理:每一步考察两个可能
Pi-1
Ti
的像素点中那一个更靠近理
t
论圆周,从而推出沿圆周的
s
整数位置。
为计算方便,先将圆心(xc,yc)
Si
移到原点(0,0)。
算法:
* 沿x方向每次递增1个单位,从x=0开始,x=y结束,起点坐
标(0,r)
* 已知Pi-1(xi-1,yi-1)是最接近圆周的像素点,那么下一个像素点 只有可能是Ti(xi-1+1,yi-1)或Si(xi-1+1,yi-1-1)
【计算机图形学】基本图形元素:圆的生成算法
【计算机图形学】基本图形元素:圆的⽣成算法圆的特征圆被定义为到给定中⼼位置(xc,yc)距离为r的点集。
圆⼼位于原点的圆有四条对称轴x=0,y=0, x=y和x=-y。
若已知圆弧上⼀点(x,y),可以得到其关于四条对称轴的其它7个点,这种性质称为⼋分对称性。
因此,只要扫描转换⼋分之⼀圆弧,就可以求出整个圆弧的象素集。
显⽰圆弧上的⼋个对称点的算法:void CirclePoints(int x,int y,int color){ Putpixel(x,y,color); Putpixel(y,x,color);Putpixel(-x,y,color); Putpixel(y,-x,color);Putpixel(x,-y,color); Putpixel(-y,x,color);Putpixel(-x,-y,color); Putpixel(-y,-x,color);}中点画圆算法果我们构造函数 F(x,y)=x2+y2-R2,则对于圆上的点有F(x,y)=0,对于圆外的点有F(x,y)>0,对于圆内的点F(x,y)<0 。
与中点画线法⼀样,构造判别式:d=F(M)=F(xp+1,yp-0.5)=(xp+1)2+(yp-0.5)2-R2若 d<0,则应取P1为下⼀象素,⽽且再下⼀象素的判别式为:d=F(xp+2,yp-0.5)=(xp+2)2+(yp-0.5)2-R2=d+2xp+3若d≥0,则应取P2为下⼀象素,⽽且下⼀象素的判别式为d=F(xp+2,yp-1.5)=(xp+2)2+(yp-1.5)2-R2=d+2(xp-yp)+5我们这⾥讨论的第⼀个象素是(0,R),判别式d的初始值为:d0=F(1,R-0.5)=1.25-R【算法流程图】【算法代码】void PaintArea::drawCircleMiddle(QPainter &painter,const QPoint ¢er, int r) {int x,y,deltax,deltay,d;x=0;y=r;deltax=3;deltay=2-3-3;d=1-r;while(x<y){if(d<0){d+=deltax;deltax+=2;x++;}else{d+=(deltax+deltay);deltax+=2;deltay+=2;x++;y++;}painter.drawPoint(center.x()+x,center.y()+y);painter.drawPoint(center.x()+x,center.y()-y);painter.drawPoint(center.x()-x,center.y()+y);painter.drawPoint(center.x()-x,center.y()-y);painter.drawPoint(center.x()+y,center.y()+x);painter.drawPoint(center.x()+y,center.y()-x);painter.drawPoint(center.x()-y,center.y()+x);painter.drawPoint(center.x()-y,center.y()-x);}}Bresenham画圆算法思想参见直线的Bresenham画法【算法流程图】【算法代码】void PaintArea::drawCircleBresenham(QPainter &painter,const QPoint ¢er, int r) {int x,y,delta,delta1,delta2,direction;x=0;y=r;delta=2*(1-r);while(y>=0){painter.drawPoint(x,y);if(delta<0){ delta1=2*(delta+y)-1;if(delta1<=0)direction=1; else direction=2; }else if(delta>0){ delta2=2*(delta-x)-1;if(delta2<=0)direction=2; else direction=3; }else direction=2;switch(direction){case 1:x++;delta+=2*x+1; break;case 2:x++; y--; delta+=2*(x-y+1); break;case 3:y--;delta+=(-2*y+1); break;}}}椭圆弧⽣成算法基本同圆弧算法,只是⽅程变得复杂F(x,y)=(bx)^2+(ay)^2-(ab)^2.对称性:4分对称,画第⼀象限分段依据:斜率为⼀点上段圆弧:下段圆弧:【椭圆中点算法流程图】【算法代码】void PaintArea::drawEllipseMiddle(QPainter &painter,int xCenter,int yCenter, int Rx, int Ry) {int Rx2=Rx*Rx;int Ry2=Ry*Ry;int twoRx2=2*Rx2;int twoRy2=2*Ry2;int p,x=0,y=Ry,px=0,py=twoRx2*y;void ellipsePlotPoints(QPainter&,int,int,int,int);ellipsePlotPoints(painter,xCenter,yCenter,x,y);//Region1p=round(Ry-(Rx2*Ry)+(0.25*Rx2));while(px<py){x++;px+=twoRy2;if(p<0)p+=Ry2+px;else{y--;py-=twoRx2;p+=Ry2+px-py;}ellipsePlotPoints(painter,xCenter,yCenter,x,y);}//Region2p=round(Ry2*(x+0.5)*(x+0.5)+Rx2*(y-1)*(y-1)-Rx2*Ry2);while(y>0){y--;py-=twoRx2;if(p>0)p+=Rx2-py;else{ x++;px+=twoRy2;p+=Rx2-py+px;}ellipsePlotPoints(painter,xCenter,yCenter,x,y);}}void ellipsePlotPoints(QPainter &painter,int xCenter,int yCenter,int x,int y){ painter.drawPoint(xCenter+x,yCenter+y);painter.drawPoint(xCenter-x,yCenter+y);painter.drawPoint(xCenter+x,yCenter-y);painter.drawPoint(xCenter-x,yCenter-y);}软件截图这个绘图软件是⽤QT写的,我会另外写⼀篇介绍编程结构,待续~转载请注明出处:。
计算机图形学第3章 基本图形生成算法
例题:有点P0(4,3);P1(6,5);P2(10,
6 );P3(12,4),用以上4点构造2次B样条曲线。
2.1.7 非均匀有理B样条
非均匀有理B样条NURBS(Non Uniform Rational BSpline);
3.2.2
Bresenham画圆法
该算法是最有效的算法之一。
不失一般性,假设圆心(xc,yc) ,圆上的点(x′,y′),则:
x' x xc
y ' y yc
圆心为原点,半径为R的位于第一象限1/8圆弧的画法,即(0, R)~( R , R )。
2 2
yi ), 思想:每一步都选择一个距离理想圆周最近的点P( xi , 使其误差项最小。
画其他曲线。
3.3
自由曲线的生成
正弦函数曲线
指数函数曲线
多项式函数曲线
自 由 曲 线
概率分布曲线及样条函数曲线
3.3.1 曲线的基本理论
基本概念
2.1.4
规则曲线:可用数学方程式表示出来的,如抛物 线等。
自由曲线:很难用一个数学方程式描述的,如高
速公路等。可通过曲线拟合(插值、逼近)的方法来
例题: 利用Bresenham算法生成P (0,0)到Q(6,5)的直 线所经过的像素点。要求先 列出计算式算出各点的坐标 值,然后在方格中标出各点。
(1,1)
3.1.5 双步画线法 原理
模式1:当右像素位于右下角时,中间像素位于底线 模式4:当右边像素位右上角时,中间像素位于中线 模式2和模式3:当右像素位于中线时,中间像素可能位于底线 上,也可能位于中线上,分别对应于模式2和模式3,需进一步 判断。 当0≤k≤1/2时,模式4不可能出现,当1/2≤k≤1时,模式1不 可能出现。
电脑图形教程基本图形生成算法
P2
e’
e P P1
y方向不走步
P2
e
e’
P
P1
Bresenham画线算法(6/7)
下一步误差的计算
当e≥0时,y方向走一步
e’=2y/ x - 1 =e + y/ x - 1 e’=e + 2y - 2x
当e<0时,y方向不走步
e’=2y/ x=e + y/ x e’=e + 2y
P2
光栅图形中点的表示
Address(x,y) = (xmax-xmin) * (y-ymin) + (x-xmin) + 基地址 = k1 + k2y + x
对像素连续寻址时,如何减少计算量?
Address(x±1,y) = k1 + k2y + (x±1) = Address(x,y) ± 1 Address(x,y±1) = k1 + k2(y ±1) + x = Address(x,y) ± k2 Address(x±1,y±1) = k1 + k2(y ±1) + (x±1)
实区域填充 字符 图形反走样
光栅图形中点的表示
…
地址线性表 1D表示
(x,y)坐标
显示屏幕 2D表示
像素由其左下角坐标表示
光栅图形中点的表示
y ymax
ymin xmin
x xmax
地址 = (xmax-xmin) * (y-ymin) + (x-xmin) + 基地址
每行像素点数
行数
行中位置
P2
M (Xp+1,Yp+0.5)
P
第2章基本图形生成算法
if (Flag) { //X方向单位增量
for (n=0; n<= Length; n++) {//X方向插补过程
WritePixel(ix, Round(y), value); ix+=idx; y+=dy; } //End of for } //End of if else { //Y方向斜率增量
第 2 章 基本图形生成算法(Ⅰ)
1) Bresenham的基本原理
假定直线斜率 k在 0~1之间 。 此时 , 只需考
虑 x方向每次递增 1个单位 , 决定 y方向每次 递增 0或 1。
设直线的
当前点为 (xi,y) 当前光栅点为 (xi,yi)
下一个
直线的点应为 (xi+1,y+k) 直线的光栅点
y
y 2
y1
k
x x2 x1
第 2 章 基本图形生成算法(Ⅰ)
1)David F. Rogers 描述描述
如果已知第 i点的坐标 , 可用步长 StepX 和 StepY得到
第 i+1点的坐标为 : – xi+1=xi+ StepX – yi+1=yi+ StepY 或 yi+1=yi+ k * StepX
Bresenham算法
– 基本原理 – Bresenham算法 – 整数 Bresenham算法 – 一般整数 Bresenham算法
第 2 章 基本图形生成算法(Ⅰ)
2.1.1 DDA算法算法
1)David F. Rogers 描述描述
直线的基本微分方程是 :
dy dx = 常数 (k)
设直线通过点 P1(x1,y1)和P2(x2,y2) , 则直线方程可表示为 :
CG No3-基本图元生成-1
LinYi University School of Informatics Wang Libo
Computer Graphics 计算机图形学
程序实现
DDALine(int X0,int Y0,int X0,int Y0,Color color) { int X float dx,dy,k,y dx=x1-x0; dy=y1-y0; k=dy/dx; y=Y0; for(x=X0;x<=X1;x++){ putpixel(x,int(y+0.5),Color); y=y+k; } }
getch(); closegraph( ); }
LinYi University School of Informatics Wang Libo
Computer Graphics 计算机图形学
2、逐点比较法
1.偏差计算 <0 画笔在OA下方,走+y 一步 d=tgβ-tgα = =0 画笔在OA上,走+x 一步 >0 画笔在OA上方,走+ x 一步 第一象限: d=ym/xm—yA/xA=(ymxA-yAxm)/xAxm 判别式:Fm=ymxA-xmyA >=0 走+x <0 走+y
Computer Graphics 计算机图形学
Computer Graphics
计算机图形学
基本图元的生成
LinYi University School of Informatics Wang Libo
Computer Graphics 计算机图形学
第二章 基本图元生成算法
几何图形G={Pi | Pi 最接近图形的象素 }
基本图形元素生成算法
实验一基本图形元素生成算法1.实验目的:(1)掌握基本图形元素生成算法。
(2)了解高级语言的图形模式的设定和对基本图形类(或函数)的调用方法。
2.实验内容:选定Bresenham算法,编写生成该基本图形的源程序,并能在计算机上编译运行,画出正确的图形。
3.实验步骤:Bresenham算法是计算机图形学领域使用最广泛的直线扫描转换方法。
原理:过各行、各列像素中心构造一组虚拟网格线,按直线从起点到终点的顺序计算直线各垂直网格线的交点,然后确定该列像素中与此交点最近的像素。
此算法的优点在于可以采用增量计算,使得对于每一列,只要检查一个误差项的符号,就可以确定该列所求的像素。
程序流程图如下:程序如下function MidBresenhamline( x0, y0, x1,y1) if x0>x1x=x1;x1=x0;x0=x;y=y1;y1=y0;y0=y;endx=x0;y=y0;dx=x1-x0;dy=y1-y0;d=dx-2*dy;UpIncre=2*dx-2*dy;DownIncre=-2*dy;while x<=x1axis([x0 x1 y0 y1])plot([x],[y],'*');grid onhold onx=x+1;if d<0y=y+1;d=d+UpIncre;elsed=d+DownIncre;endpause(0.1);endt=x0:1:x1yy=(y1-y0)./(x1-x0)*t+(y1-((y1-y0)./(x1-x0)*x1)); plot(t,yy)程序运行如下>> MidBresenhamline( 0, 0, 8,5)t =0 1 2 3 4 5 6 7 8>> MidBresenhamline( 0, 0, 500,750)运行过程中的截图效果4.实验总结:1.通过学习使用中点Bresenham算法画直线,对于斜率大于1的直线段,只需交换x和y之间的规则即可。
实验二 二维基本图元的生成
yIncrement = float (dy) / float (steps);
setPixel (round (x), round (y));
for (k = 0; k < steps; k++) {
x += xIncrement;
}
注意:
(1)代码没有主函数及其它OpenGL的初始化函数,请用前面实验一中的代码进行添加,该函数在回调函数myDraw()中调用执行;
(2)代码中出现的
class scrPt {
public:
GLint x, y;
};
是C++中的类定义,对于没有学习过C++的读者,这里可看作是C语言中的一个结构体:
{
setPixel (xCenter + x, yCenter + y);
setPixel (xCenter - x, yCenter + y);
setPixel (xCenter + x, yCenter - y);
setPixel (xCenter - x, yCenter - y);
}
注意:
(1)代码没有主函数及其它OpenGL的初始化函数,请用前面实验一中的代码进行添加,该函数在回调函数myDraw()中调用执行;
*/
void ellipseMidpoint (int xCenter, int yCenter, int Rx, int Ry)
{
int Rx2 = Rx * Rx;
int Ry2 = Ry * Ry;
int twoRx2 = 2 * Rx2;
第二章 基本图元的显示1
图 形 学
第二章 基本图形元素的生成算法
(0,6)
(6,6)
(6,0)
(0,0) 计 算 机 图 形 学 (5,3)
(0,0)
第二章 基本图形元素的生成算法
扫描转换:通常把图像中的点、线、圆、区域和字符等图 形基本指令组成的显示文件转换成为显示缓冲器中图像的 位映像图的过程,成为扫描转换。 位图:是与屏幕图像每个像素点一一对应的图像矩阵, 矩阵中的每个元素就是像素的值(表示灰度级别与色 彩)。 选择扫描转换算法,速度与图像质量两者之间权衡折 衷。由于在建立一幅图形过程中,基本的图形扫描转 换算法将被调用成百上千此,因此,速度快一些是比 较可取的。
1 xi 1 x i x x i x x i 1 | x | 1 y i 1 y i y y i y y i k | y |
x=x-1;y=y-k; for(x=x1;x>=x2;x--) {putpixel(x,round(y));y=y-k;}
(X1,Y1)的像素点,对应的显示缓冲器地址为: 字节地址= S + ( H / 8 ) * Y1 + ( X1 / 8 ) 的整数部分 字节内的位地址= X1 / 8 的余数 计 算 机 图 形 学
第二章 基本图形元素的生成算法
2.1.2 直线段的生成
数学上的直线是由无数个点构成的集合,显 然,光栅显示器只能近地似显示直线。对 于水平、垂直和45°斜线是可以达到较为 满意的效果的。当我们对直线进行光栅化 时,需要确定最佳逼近该直线的一组象素。 扫描转换直线段就是计算出落在直线段上 或充分靠近它的一串像素,并以此像素近 似代替原连续直线段在屏幕上显示的过程。
计 算 机 图 形 学
计算机基本图形生成算法
x2 y2 R2
构造函数F(x,y)=x2+y2-R2。 对于圆上的点,有F(x,y)=0; 对于圆外的点,F(x,y)>0; 而对于圆内的点,F(x,y)<0。
31
y
Pu
PM
Pd
x
图5.13 中点Bresenham画圆的原理
中点Bresenham画圆
y
yi
k
19
改进的Bresenham算法
kd
k d
kd
k kd
图5.10 改进的Brensemham算法绘制直线的原理
改进的Bresenham算法——原理
xi1 yi1
xi
yi yi
1
1
(d 0.5) (d 0.5)
误差项的计算
d初=0, 每走一步:d=d+k
一旦y方向上走了一步,d=d-1
中点Bresenham画圆
判别式的初始值
d0 F ( x0 1, y0 0.5) F (1, R 0.5) 1 (R 0.5)2 R2 1.25 R
36
改进:用d-0.25代替d 此时有:
d d 2xi 3
d 0.25
d d 2(xi yi ) 5 d 0.25
yi-2
(xi 2)2 ( yi 0.5)2 R2
xi xi+1 xi+2
d2 ( xi 1 1)2 ( yi 0.5)2 R2 图5.14 d≤0的情况
( xi 1)2 2xi 3 ( yi 0.5)2 R2
d1 2xi 3
误差项的递推(d>0)
yi
P
yi-1
构造判别式:
计算机图形学基本图形生成算法
y= k· x+b
k=0.571429
b=0.428571
2 X[0]=1 y0 X[1]=2
Y[0]=1 Y[0]=1 Y[1]=kx[1]+b=1.57 Y[1]=y0+k=1.57 Y[2]=y1+k=2.14 Y[2]=kx[2]+b=2.14 Y[3]=y2+k=2.71 Y[3]=kx[3]+b=2.71 Y[4]=y3+k=3.28 Y[4]=kx[4]+b=3.28 Y[5]=y4+k=3.85 Y[5]=kx[5]+b=3.85 Y[6]=y5+k=4.4 Y[6]=kx[6]+b=4.4 Y[7]=5 Y[7]=5
第3章 基本图形生 成算法
1 直线生成算法(DDA、BRES) 2 圆生成算法(Mid) 3 多边形填充算法(扫描线、区域) 4 字符图元算法
2015/4/19
1
图元
• 图元:图形软件包中用了描述各种几何 图形元素的函数称为图形输出原语,简 称图元。 • 描述对象几何要素的输出图元一般称为 几何图元。点的定位和直线段是最简单 的几何图元。 • 在选定坐标系中指定一个图形的几何要 素后,输出图元投影到该输出设备显示 区域对于的二维平面上,并扫描转换到 帧缓存的整数像素位置。
2015/4/19
5
1 直线生成算法(DDA、BRES) 2 圆生成算法(Mid) 3 多边形填充算法(扫描线、区域) 4 字符图元算法
1 直线的DDA算法
2015/4/19
6
OpenGL画点和画线函数 1) 画点函数 glVertex*( ); (*={234}{sifd}[v]) 表示该函数有后缀,指 明空间尺寸、坐标数据类型或向量形式描述。 Ex: glBegin(GL_POINTS); glVertex2i(100,50); glEnd(); glBegin(GL_POINTS); glVertex2i(100,50); glVertex2i(75,90); glVertex2i(300,590); glEnd();
基本图元生成算法
刘春晓
y F(x,y)=0 F(x,y)>0 x F(x,y)<0 F(x,y)=0
y
F(x,y)>0
F(x,y)<0
x
图5-4
直线将平面分为三个区域
计算机图形学
刘春晓
判别式:
d i = F ( xiM , yiM ) = F ( xi + 1, yi + 0.5) = yi + 0.5 − k ( xi + 1) − b
计算机图形学
刘春晓
源程序
BresenhamCircle(int r, color)
{ int x,y,delta, d1, d2, dir x=0; y=r; delta = 2*(1-r) while(y>=0){ drawpixel(x,y,color); if(delta < 0){ d1 = 2* (delta + y) -1; if(d1 <=0) dir = 1; else dir = 2; } else if( delta > 0){ d2 = 2*(delta-x)-1; if(d2 <= 0) dir = 2; else dir = 3; } else dir = 2; 计算机图形学
x
图4-3
计算机图形学
中点Bresenham画圆的原理
刘春晓
M的坐标为:M(xi +1,yi-0.5)
• 当F(xM,yM)<0时,取Pu(xi +1,yi) • 当F(xM,yM)>0时,取Pd(xi +1,yi-1) • 当F(xM,yM)=0时,约定取Pu。
构造判别式:
d i = F ( xM , yM ) = F ( x i +1, yi − 0.5) = ( x i +1) 2 + ( yi − 0.5) 2 − R 2
第四章基本图元的生成
4.5 区域填充
基础知识: 基础知识 区域: 区域:通常由一个封闭的轮廓线来定义,处于一个 封闭轮廓线内的所有像素点即构成了一个区域。 区域填充: 区域填充:给出一个区域的边界,要求对应边界范 围内的所有像素单元赋予指定的颜色值或图案。 区域填充要解决两个问题: 区域填充要解决两个问题:一是确定需要填充哪些 像素;二是确定用什么颜色填充(实心填充)或 图案填充。 在光栅系统中有两种基本的区域填充方法: 在光栅系统中有两种基本的区域填充方法: 扫描线填色方法 种子填色方法
一般来讲,任何图形输出设备都能准确地画出水 平线X和垂直线Y,但要画出一条准确的斜线不是 件容易的事。怎样生成斜线段呢?图形显示器是 由一个个排列有序的像素构成,划分的像素点越 多分辨率越高。例如,VGA卡640×480的显示 VGA 640 480 器,分成640×480个网络,网络的单元称为像素, 一条线段就是由一些连续可见的像素所组成。画 一条直线实际上是根据一系列计算出来并与该线 靠近的像素绘制的。(见书P51)
4.4 椭圆的生成
4.4.1 概述 4.4.2 中点椭圆算法
4.4.1 概述
椭圆被定义为到两个定点(也称为焦点) 的距离之和等于常数的点的集合。假如椭 圆上任意点P=(x,y)到两个焦点F1= (x1,y1)和F2=(x2,y2)的距离之和等于 常数R,那么椭圆的通用方程可表示为: 对方程平方处理去掉根号后,椭圆的方程 可表示为:
4.5.3 种子填充
种子填充算法允许从四个方向寻找下一个 像素的,称为四向算法;允许从八个方向 搜索下一像素的,称为八向算法。八向算 法可以填充八向连通区域,也可以填充四 向连通区域。但四向算法只能填充四向连 通区域,而不能填充八向填充区域。
4.5.3 种子填充
计算机图形学教案第5章基本图形生成算法
曲面生成算法
参数曲面
通过参数方程表示曲面的几何形状,通过迭 代或数值方法计算出曲面上的点,然后连接 这些点形成曲面。
网格曲面
将曲面分割成网格形式,利用离散的点表示网格顶 点,然后连接这些顶点形成曲面。
隐式曲面
通过一系列方程定义曲面的几何形状,求解 这些方程得到曲面上的一系列点,然后连接 这些点形成曲面。
对于复杂的多边形或不规则形状,可能会出现填充不准确或过度填充的情况。
05
其他基本图形生成算法
椭圆生成算法
参数方程法
通过参数方程表示椭圆的几何形状,通过迭代或数值方法计算出椭 圆上的点,然后连接这些点形成椭圆。
中心点法
以椭圆中心为中心,根据椭圆的长短轴半径和旋转角度,计算出椭 圆上的一系列点,然后连接这些点形成椭圆。
THANK YOU
感谢聆听
03
圆生成算法
圆生成算法的原理
圆上取点
通过在圆周上等距离取点,并将这些点连接起来形成 多边形,最终将多边形平滑过渡成圆形。
参数方程法
利用圆的参数方程,通过计算角度和半径来获取圆上 的点。
中点圆算法
利用中点坐标和半径计算圆上的点,通过迭代的方式 逐步逼近圆周。
圆生成算法的实现
使用数学库
利用数学库中的函数来计算圆的参数方程, 获取圆上的点。
两点式方程
给定直线上的两个点,可以推导出直线的两点式方程 。
直线生成算法的实现
参数化方程
将直线上任意点的坐标示为 参数方程的形式。
参数值计算
根据起点和终点坐标,计算参 数值。
绘制点
根据参数值,在屏幕上绘制对 应的点。
直线生成算法的优缺点
优点
简单易实现,适用于各种类型的直线 。
基本图形生成算法原理
基本图形生成算法原理现在的计算机能够生成各种复杂的图形,但无论其多么复杂,它都是由一些基本图形组合而成的。
因此,学习基本图形的生成算法是掌握计算机图形的基础。
本章就主要讨论一些基本图形的生成原理,如点、直线、椭圆生成。
如前面所述,目前我们使用的主要图形输出设备显示器(一般为光栅图形显示器)和打印机(喷墨、激光打印机)本质上是一种画点设备,是由一定数量的网络状细小光点(即像素)组成,使某些像素亮(将帧缓存中对应位置的值为1)和某些像素不亮(将帧缓存中对应位置的值为0)来显示图形。
因此,基本图形生成的原理是指在点阵输出设备的情况下,如何尽可能地输出最接近于原图形(理想图形)的直线或曲线图形,即以最快的速度确定最佳逼近于图形的像素集。
确定图形的像素集合并显示的过程常称之为图形的扫描转换或光栅化。
这一过程使用的计算方法称之为图形生成算法。
1 点2 直线段的生成直线是点的集合,几何学中的一条直线是由两点决定,直线在数学上可以有多种表示方法,而在计算机图形学里,直线是由离散的像素点逼近理想直线段的点的集合。
数学上的直线是没有宽度的,而计算机图形学中显示出的直线的宽度与像素点的大小有关,一个像素宽的直线的线粗为像素的边长。
由计算机生成的图形中有大量的直线段,而且曲线也是由一系列短直线段逼近生成的。
因此,研究直线生成的方法是计算机图形学的基本问题之一。
对计算机生成直线的一般要求是:线段端点的位置要准确;构成线段的像素点的集合应尽可能分布均匀,其密度应该与线段的方向及长度无关;线段生成的速度要快。
生成直线的算法有多种,这里仅介绍两种方法,即DDA 算法和Bresenham 算法。
2.1 直线DDA 算法该直线生成算法称为数值微分算法(Digital Differential Analyzer 简称DDA )。
它是一种根据直线的微分方程来产生直线的方法。
设直线的起点坐标为),(s s y x ,终点坐标为),(e e y x ,则=dx dy k xy x x y y s e s e =∆∆=-- (3-1)k 是直线的斜率。
04 基本图形(元)生成技术
if (d<0) { x++; y++; d+=delta2; //取P2,并且计算下一点的d值 } else { x++; d+=delta1; //取P1,并且计算下一点的d值 } putpixel(x,y,color); } }
当|k|≤1时,让x每步增加1,y最多增加1,
然后用四舍五入的方法来确定直线上的
像 素 位 置 为 (x,round(y)) 。 设 当 前 点 为 (xi,yi),则下一个像素xi+1 = xi +1,则 yi+1 =k xi+1 +B =k(xi+1)+B=(k xi +B)+k = yi +k 即当x每递增1时,y递增斜率k。
即可。
算法举例:
设直线的起点为(0,0),终点为(5, 3),按Bresenham 算法计算并确定个 像素点位置。
计算dx=5,dy=3,k=3/5=0.6,误差e=-0.5; x=0,y=0
(1) i=0: 输出像素(0,0)
x=1,e=e+k=-0.5+0.6=0.1>0, 则 有
y=y+1=1,e=e-1=0.1-1=-09
其中,a=y0-y1,b=x1-x0,c=x0y1-x1y0。
对于直线中的点,则有F(x,y)=0;对于直 线上方的点,则有F(x,y)>0;对于直线下 方的点,则有F(x,y)<0。
• 判断中点M在Q的上方,还是 在下方,只要将中点坐标 M(xi+1,yi+0.5) 代 入 F(x,y) 方 程 中,并判断它的符号。构造判 别式
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基本图元的生成算法一、实验目的1、初步了解显示窗口与视区的关系2、掌握OpengGL点、直线、多边形的绘制3、掌握DDA直线生成算法。
4、掌握Bresenham直线生成算法二、实验环境硬件要求:PC机,主流配置,最好为独立显卡,显存512M以上。
软件环境:操作系统:Windows XP。
语言开发工具:VC6.0。
三、实验内容与要求1、调出实验一的源代码运行,调整修改使得显示窗口大小改变时,绘制的矩形大小随之改变。
如图2-1所示。
提示:(1)在main函数里添加注册窗口变化函数glutReshapeFunc(myreshape); (放在glutMainLoop()之前)(2)在程序中添加窗口改变子函数,参数w,h为当前显示窗口的宽和高void myreshape(GLsizei w, GLsizei h){glViewport(0,0,w,h); //设置视区位置glMatrixMode(GL_PROJECTION);//设置投影变换模式glLoadIdentity(); //调单位矩阵,清空当前矩阵堆栈if(w<=h)gluOrtho2D(0,300,0,300*(GLfloat)h/(GLfloat)w);//设置裁剪窗口大小elsegluOrtho2D(0,300*(GLfloat)w/(GLfloat)h,0,300);}a) 显示窗口改变前 b)显示窗口变大后未修改前的初始源程序参考如下:/*my first program.cpp*/#include <glut.h>void display(void){glClear(GL_COLOR_BUFFER_BIT); //刷新颜色缓冲区glRectf(0,0,0.5,0.5);glFlush(); //用于刷新命令队列和缓冲区,使所有尚未被执行的OpenGL命令得到执行}void main(int argc, char** argv){glutInit(&argc, argv); //初始化GLUT库glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); //设置显示模式 glutInitWindowSize(100, 200);glutCreateWindow("hello"); //创建窗口,标题为“hello”glutDisplayFunc(display); //用于绘制当前窗口glutMainLoop(); //表示开始运行程序,用于程序的结尾}2、自己参照讲义或教材按照自己的构思画二维平面图形, 修改样本程序circle-algorithm.cpp将上面的矩形替换成自己构思的二维平面图形。
注意顶点的顺序。
参考函数:(1)、点绘制举例glPointSize(2.0) //点的大小设置glBegin(GL_POINTS);glColor3f(1.0,1.0,1.0);glVertex2f(-0.5,-0.5); //顶点glColor3f(1.0,0.0,1.0);glVertex2f(-0.5,0.5);glColor3f(0.0,1.0,1.0);glVertex2f(0.5,0.5);glColor3f(1.0,1.0,0.0);glVertex2f(0.5,-0.5);glEnd()(2)、直线/三角形/四边形绘制举例glLineWidth(2.0);glBegin(GL_LINES);// glBegin(GL_LINE_STRIP);// glBegin(GL_LINE_LOOP);// glBegin(GL_TRIANGLES);// glBegin(GL_TRIANGLE_STRIP);// glBegin(GL_TRIANGLE_FAN);// glBegin(GL_QUADS);// glBegin(GL_TRIANGLE_STRIP);glVertex2f(-0.5,0.5);glVertex2f(-0.5,-0.5);glColor3f(1.0,1.0,1.0);glVertex2f(-0.5,0.5);glColor3f(1.0,1.0,0.0);glVertex2f(0.5,-0.5);glEnd();(3)、多边形举例glBegin(GL_POLYGON);glVertex2f(-0.5,0.5);glVertex2f(-0.5,-0.5);glColor3f(1.0,1.0,1.0);glVertex2f(0,-0.5);glColor3f(1.0,1.0,0.0);glVertex2f(0.5,-0.5);glVertex2f(0.5,0.5);glEnd();3、读懂DDA直线生成算法伪代码,并修改伪代码,使之变成可行的OpenGL代码,验证DDA直线生成算法。
DDA直线生成伪代码//x0,y0 表示直线的起始点, x1,y1表示直线的终止点,color表示直线的绘制颜色void DDA_line(int x0, int y0, int x1, int y1,int color){int dx = x1 – x0, dy = y1 – y0, k;float xIncrement , yIncrement ,steps, x = x0, y = y0;if (abs (dx) > abs (dy)) steps = abs (dx);else steps = abs (dy);xIncrement = (float) (dx) /steps;yIncrement = (float) (dy) /steps;for (k =0; k<steps; k++){Setpixel(round(x), round(y),color);x += xIncrement; y += yIncrement;}}提示:使用学过的画点函数替换setpixel(round(x), round(y),color)函数。
图2-24、读懂Bresenham直线生成算法伪代码,并修改伪代码,使之变成可行的OpenGL代码,验证Bresenham直线生成算法。
要求在函数void Bresenham_Circle_Algorithm(int cx, int cy, int radius)中写出自己的Bresenham画圆法代码。
思考选做:5、DDA算法来绘制N多边形。
用n多边形逼近圆,最小多边形为3角形。
将自己的代码写在函数NSidedPolygon(int n, int cx, int cy,int radius)里,使用DDA算法来绘制N多边形(不要使用OpenGL绘制多边形的函数)。
我们知道OpenGL画点功能为:glBegin(GL_Points);glVertex2f(x,y);glEnd();由于n多边形有n条边,所以必须画n条直线。
将画直线的代码写在函数 DrawLine(int x1, int y1, int x2, int y2)中,考虑n多边形的n条直线是各个方向,即有斜率|k|>=1的情况,又有斜率|k|<1的情况,你可以使用学过的画直线方法,如DDA算法。
阅读样本程序,参见circle-algorithm.cpp:附:样本程序circle-algoritm.cpp#include <glut.h>#include <stdio.h>#include <stdlib.h>#include <math.h>// set some initial parameters, such as the center of the circle(cx,cy), the radius of the circle,int cx=150,cy=150,radius=80;void DDA_Line(int x1,int y1,int x2,int y2);void Bresenham_DrawLine(int x1,int y1,int x2,int y2);void NSidedPolygon(int n, int cx, int cy, int radius);void Display(void);void Reshape(int w, int h);int main(int argc, char** argv){glutInit(&argc, argv);glutInitWindowPosition(0, 0);glutInitWindowSize(window_width, window_height); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);glutCreateWindow("Circle Generation Algorithm"); glutDisplayFunc(Display);glutReshapeFunc(Reshape);glutMainLoop();return 0;}void Display(void){/* YOUR CODE HERE */glutSwapBuffers();}void Reshape(int w, int h){glMatrixMode(GL_PROJECTION);glLoadIdentity();glViewport(0, 0, w, h);gluOrtho2D(0, w, 0, h);// glutPostRedisplay();}void DDA_Line(int x1,int y1,int x2,int y2);{/* YOUR CODE HERE */}void Bresenham_DrawLine(int x1,int y1,int x2,int y2); {/* YOUR CODE HERE */}void NSidedPolygon(int n, int cx, int cy, int radius) {/* YOUR CODE HERE */}。