c语言计算机图形来画八分画圆,【计算机图形学】基本图形元素:圆的生成算法...

08年9月入学,12年7月毕业,结束了我在软件学院愉快丰富的大学生活。此系列是对四年专业课程学习的回顾,索引参见:http://blog.csdn.net/xiaowei_cqu/article/details/7747205

圆的特征

圆被定义为到给定中心位置(xc,yc)距离为r的点集。圆心位于原点的圆有四条对称轴x=0,y=0, x=y和x=-y。若已知圆弧上一点(x,y),可以得到其关于四条对称轴的其它7个点,这种性质称为八分对称性。因此,只要扫描转换八分之一圆弧,就可以求出整个圆弧的象素集。

824febee7d9446e3bbe37d1c3c9ec6d5.jpg

显示圆弧上的八个对称点的算法:

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

a9b16f7495654ea798ad83d229ac6bc9.png

【算法流程图】

0f3f317a8d74475fad2e51fbd37f8ad3.png

【算法代码】

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

{

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画法 【计算机图形学】基本图形元素:直线的生成算法

【算法流程图】

3a98da4595dd4eca979d209eda1b44c8.jpg

【算法代码】

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分对称,画第一象限

分段依据:斜率为一点

6a48490f07c1696cf22115ceecead164.png 66a4fd1d46c9282571859d2efdfb254d.png

上段圆弧:

fd2ab2c99ffdc17896bfcd2a78a543cb.png

下段圆弧:

814aa152b899b7f31c5414ba386e8f6a.png

【椭圆中点算法流程图】

7716cffb12322ca4cf77077c07d11429.png

【算法代码】

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);

//Region1

p=round(Ry-(Rx2*Ry)+(0.25*Rx2));

while(px

x++;

px+=twoRy2;

if(p<0)

p+=Ry2+px;

else{

y--;

py-=twoRx2;

p+=Ry2+px-py;

}

ellipsePlotPoints(painter,xCenter,yCenter,x,y);

}

//Region2

p=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);

}

软件截图

cb2dd9ccdb4e42a8bbd6071a503c7aff.jpg

这个绘图软件是用QT写的,我会另外写一篇介绍编程结构,待续~

转载请注明出处:http://blog.csdn.net/xiaowei_cqu/article/details/7909607

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值