计算机视觉
图像处理

【计算机图形学】基本图形元素:圆的生成算法

文章目录

的特征

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

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

  1. void CirclePoints(int x,int y,int color)
  2. { Putpixel(x,y,color); Putpixel(y,x,color);
  3.   Putpixel(-x,y,color); Putpixel(y,-x,color);
  4.   Putpixel(x,-y,color); Putpixel(-y,x,color);
  5.   Putpixel(-x,-y,color); Putpixel(-y,-x,color);
  6. }


中点画圆算法

果我们构造函数 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

【算法流程图】

【算法代码】

  1. void PaintArea::drawCircleMiddle(QPainter &painter,const QPoint ¢er, int r)
  2. {
  3.     int x,y,deltax,deltay,d;
  4.     x=0;y=r;
  5.     deltax=3;deltay=2-3-3;d=1-r;
  6.     while(x<y)
  7.     {
  8.         if(d<0)
  9.         {
  10.             d+=deltax;
  11.             deltax+=2;
  12.             x++;
  13.         }
  14.         else
  15.         {
  16.             d+=(deltax+deltay);
  17.             deltax+=2;deltay+=2;
  18.             x++;y++;
  19.         }
  20.         painter.drawPoint(center.x()+x,center.y()+y);
  21.         painter.drawPoint(center.x()+x,center.y()-y);
  22.         painter.drawPoint(center.x()-x,center.y()+y);
  23.         painter.drawPoint(center.x()-x,center.y()-y);
  24.         painter.drawPoint(center.x()+y,center.y()+x);
  25.         painter.drawPoint(center.x()+y,center.y()-x);
  26.         painter.drawPoint(center.x()-y,center.y()+x);
  27.         painter.drawPoint(center.x()-y,center.y()-x);
  28.     }
  29. }

Bresenham画圆算法

思想参见直线的Bresenham画法 【计算机图形学】基本图形元素:直线的生成算法

【算法流程图】

【算法代码】

  1. void PaintArea::drawCircleBresenham(QPainter &painter,const QPoint ¢er, int r)
  2. {
  3.     int x,y,delta,delta1,delta2,direction;
  4.     x=0;y=r;
  5.     delta=2*(1-r);
  6.     while(y>=0)
  7.     {
  8.        painter.drawPoint(x,y);
  9.         if(delta<0)
  10.         {   delta1=2*(delta+y)-1;
  11.             if(delta1<=0)direction=1; else direction=2; }
  12.         else if(delta>0)
  13.         {   delta2=2*(delta-x)-1;
  14.             if(delta2<=0)direction=2; else direction=3; }
  15.         else  direction=2;
  16.         switch(direction)
  17.         {case 1:
  18.             x++;delta+=2*x+1; break;
  19.         case 2:
  20.             x++; y–; delta+=2*(x-y+1); break;
  21.         case 3:
  22.             y–;delta+=(-2*y+1); break;
  23.         }
  24.     }
  25. }


椭圆弧生成算法

基本同圆弧算法,只是方程变得复杂F(x,y)=(bx)^2+(ay)^2-(ab)^2.
对称性:4分对称,画第一象限
分段依据:斜率为一点

 

上段圆弧:

下段圆弧:

 

【椭圆中点算法流程图】

 

【算法代码】

  1. void PaintArea::drawEllipseMiddle(QPainter &painter,int xCenter,int yCenter, int Rx, int Ry)
  2. {
  3.     int Rx2=Rx*Rx;
  4.     int Ry2=Ry*Ry;
  5.     int twoRx2=2*Rx2;
  6.     int twoRy2=2*Ry2;
  7.     int p,x=0,y=Ry,px=0,py=twoRx2*y;
  8.     void ellipsePlotPoints(QPainter&,int,int,int,int);
  9.     ellipsePlotPoints(painter,xCenter,yCenter,x,y);
  10.     //Region1
  11.     p=round(Ry-(Rx2*Ry)+(0.25*Rx2));
  12.     while(px<py){
  13.         x++;
  14.         px+=twoRy2;
  15.         if(p<0)
  16.             p+=Ry2+px;
  17.         else{
  18.             y–;
  19.             py-=twoRx2;
  20.             p+=Ry2+px-py;
  21.         }
  22.         ellipsePlotPoints(painter,xCenter,yCenter,x,y);
  23.     }
  24.     //Region2
  25.     p=round(Ry2*(x+0.5)*(x+0.5)+Rx2*(y-1)*(y-1)-Rx2*Ry2);
  26.     while(y>0){
  27.         y–;
  28.         py-=twoRx2;
  29.         if(p>0)
  30.             p+=Rx2-py;
  31.         else{ x++;
  32.             px+=twoRy2;
  33.             p+=Rx2-py+px;
  34.         }
  35.         ellipsePlotPoints(painter,xCenter,yCenter,x,y);
  36.     }
  37. }
  38. void ellipsePlotPoints(QPainter &painter,int xCenter,int yCenter,int x,int y)
  39. {    painter.drawPoint(xCenter+x,yCenter+y);
  40.      painter.drawPoint(xCenter-x,yCenter+y);
  41.      painter.drawPoint(xCenter+x,yCenter-y);
  42.      painter.drawPoint(xCenter-x,yCenter-y);
  43. }


软件截图

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

转载注明来源:CV视觉网 » 【计算机图形学】基本图形元素:圆的生成算法

分享到:更多 ()
扫描二维码,给作者 打赏
pay_weixinpay_weixin

请选择你看完该文章的感受:

0不错 0超赞 0无聊 0扯淡 0不解 0路过

评论 4

评论前必须登录!