搜索
bottom↓
回复: 26

用C语言怎么画圆呢?

[复制链接]

出0入0汤圆

发表于 2012-3-29 15:34:19 | 显示全部楼层 |阅读模式
请问谁懂C语言画圆的原理?无穷多边形吗

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2012-3-29 15:52:02 | 显示全部楼层
  1. /********************************************/
  2. /* 画圆数学方程(X-Ox)^2+(Y-Oy)^2=Rx^2 */
  3. /********************************************/
  4. void GUI_circle( unsigned char Ox,unsigned char Oy,unsigned char Rx,unsigned char s )
  5. {
  6.     unsigned int xx,rr;
  7.     unsigned int xt,yt;
  8.     unsigned int rs,row,col;
  9.     yt = Rx;
  10.     rr = ( unsigned int )Rx*Rx+1; // 补偿1 修正方形
  11.     rs = ( yt+( yt>>1 ) )>>1; // (*0.75)分开1/8圆弧来画
  12.     for ( xt=0; xt<=rs; xt++ )
  13.     {
  14.         xx = xt*xt;
  15.         while ( ( yt*yt )>( rr-xx ) )
  16.         {
  17.             yt--;
  18.         }
  19.         row = Ox+xt; // 第一象限
  20.         col = Oy-yt;
  21.         LCD_Point( row,col,s );
  22.         row = Ox-xt; // 第二象限
  23.         LCD_Point( row,col,s );
  24.         col = Oy+yt; // 第三象限
  25.         LCD_Point( row,col,s );
  26.         row = Ox+xt; // 第四象限
  27.         LCD_Point( row,col,s );
  28.         //***************45度镜象画另一半***************
  29.         row = Ox+yt; // 第一象限
  30.         col = Oy-xt;
  31.         LCD_Point( row,col,s );
  32.         row = Ox-yt; // 第二象限
  33.         LCD_Point( row,col,s );
  34.         col = Oy+xt; // 第三象限
  35.         LCD_Point( row,col,s );
  36.         row = Ox+yt; // 第四象限
  37.         LCD_Point( row,col,s );
  38.     }
  39. }
复制代码

出0入0汤圆

发表于 2012-3-29 16:00:58 | 显示全部楼层
解释几何上不是有园的方程吗? (x-a)^2+(y-b)^2=r^2,圆心O(a,b),半径r。 只有两个未知数,跟画直线的原理一样的。只是需要用到平方,开方,等数学函数库。

有或者看看极坐标上面有没有方便点的办法,或者三角函数什么的 ...

愚见

出0入0汤圆

发表于 2012-3-29 19:32:48 | 显示全部楼层
哪里会无穷多边形?  如果显示出来就会被量化成像有限个素点  如果不画出来,那就看你需要的精度(太高精度实在没必要)

出0入0汤圆

发表于 2012-3-29 19:35:26 | 显示全部楼层
#include <graphics.h>
void main()
{
        int gdriver=DETECT,gmode;
        initgraph(&gdriver,&gmode,"c:\\tc");
        cleardevice();
        moveto(160,120);
        lineto(480,120);
        lineto(480,360);
        lineto(160,360);
        lineto(160,120);
        getch();
        closegraph();
}

出0入0汤圆

发表于 2012-3-29 19:37:03 | 显示全部楼层
可以看看这个

http://www.ourdev.cn/forum.php?m ... st%3D1%26digest%3D1

出30入25汤圆

发表于 2012-3-29 20:20:29 | 显示全部楼层
51的麻烦在于需要尽量减少浮点运算,math.h没有十足必要真的别引进来……

出0入0汤圆

发表于 2012-3-30 07:58:43 来自手机 | 显示全部楼层
X=Rcos(A)+X0
Y=Rsin(A)+Y0
A从0到6.28
然后画点

出0入0汤圆

发表于 2012-3-30 13:55:38 | 显示全部楼层
y574924080 发表于 2012-3-29 19:37
可以看看这个

http://www.ourdev.cn/forum.php?mod=viewthread&tid=5462626&extra=page%3D1%26filter%3Ddi ...

谢谢,这个贴总结的很多啊!

出0入0汤圆

发表于 2012-3-30 18:25:17 | 显示全部楼层
51yyaayya 发表于 2012-3-30 13:55
谢谢,这个贴总结的很多啊!

不用,

大家互帮互助~~~~~~~

出0入0汤圆

发表于 2012-3-30 19:18:26 | 显示全部楼层
本帖最后由 cqv 于 2012-3-30 19:22 编辑

当年不知道从那抄的。。
  1. void LCD_Circle (unsigned int x, unsigned int y, unsigned int r, unsigned int color)
  2. {
  3.         int a, b;
  4.         int di;

  5.         a = 0;
  6.         b = r;
  7.         di = 3 - 2 * r;                                //判断下个点位置的标志
  8.         while (a <= b)
  9.         {
  10.                 LCD_Point (x - b, y - a, color);        //3           
  11.                 LCD_Point (x + b, y - a, color);        //0           
  12.                 LCD_Point (x - a, y + b, color);        //1      
  13.                 LCD_Point (x - b, y - a, color);        //7           
  14.                 LCD_Point (x - a, y - b, color);        //2            
  15.                 LCD_Point (x + b, y + a, color);        //4               
  16.                 LCD_Point (x + a, y - b, color);        //5
  17.                 LCD_Point (x + a, y + b, color);        //6
  18.                 LCD_Point (x - b, y + a, color);
  19.                 a++;

  20.                 /***使用Bresenham算法画圆**/
  21.                 if (di < 0)
  22.                         di += 4 * a + 6;
  23.                 else
  24.                 {
  25.                         di += 10 + 4 * (a - b);
  26.                         b--;
  27.                 }
  28.                 LCD_Point (x + a, y + b, color);
  29.         }
  30. }
复制代码

出0入0汤圆

发表于 2012-3-30 19:51:22 | 显示全部楼层
我用的这个
  1. void LCD_DrawFullCircle(rt_uint16_t Xpos, rt_uint16_t Ypos, rt_uint16_t Radius, rt_uint16_t Circle_colour, rt_uint16_t full_or_not)
  2. {
  3.   int32_t  D;    /* Decision Variable */
  4.   uint32_t  CurX;/* Current X Value */
  5.   uint32_t  CurY;/* Current Y Value */
  6.   D = 3 - (Radius << 1);
  7.   CurX = 0;
  8.   CurY = Radius;   
  9.   
  10.   
  11.   
  12.   D = 3 - (Radius << 1);
  13.   CurX = 0;
  14.   CurY = Radius;
  15.   while (CurX <= CurY)
  16.   {
  17.     if(full_or_not!=0)
  18.     {
  19.       LCD_DrawLine_HORIZONTAL(Xpos - CurX, Ypos + CurY, 2*CurX, Circle_colour);
  20.       LCD_DrawLine_HORIZONTAL(Xpos - CurX, Ypos - CurY, 2*CurX, Circle_colour);
  21.       
  22.       LCD_DrawLine_HORIZONTAL(Xpos - CurY, Ypos + CurX, 2*CurY, Circle_colour);
  23.       LCD_DrawLine_HORIZONTAL(Xpos - CurY, Ypos - CurX, 2*CurY, Circle_colour);
  24.     }
  25.     else
  26.     {
  27.       DrawPixel(Xpos + CurX, Ypos + CurY, Circle_colour);
  28.       DrawPixel(Xpos + CurX, Ypos - CurY, Circle_colour);
  29.       DrawPixel(Xpos - CurX, Ypos + CurY, Circle_colour);
  30.       DrawPixel(Xpos - CurX, Ypos - CurY, Circle_colour);
  31.       DrawPixel(Xpos + CurY, Ypos + CurX, Circle_colour);
  32.       DrawPixel(Xpos + CurY, Ypos - CurX, Circle_colour);
  33.       DrawPixel(Xpos - CurY, Ypos + CurX, Circle_colour);
  34.       DrawPixel(Xpos - CurY, Ypos - CurX, Circle_colour);
  35.     }
  36.    
  37.     if (D < 0)
  38.     {
  39.       D += (CurX << 2) + 6;
  40.     }
  41.     else
  42.     {
  43.       D += ((CurX - CurY) << 2) + 10;
  44.       CurY--;
  45.     }
  46.     CurX++;
  47.   }
  48. }
复制代码

出0入0汤圆

发表于 2012-3-31 10:10:19 来自手机 | 显示全部楼层
有个算法来着,br什么,一时忘记了

出0入0汤圆

发表于 2012-4-18 17:21:57 | 显示全部楼层
cqv 发表于 2012-3-30 19:18
当年不知道从那抄的。。

你这个程序的原理是什么?看不明白啊!while(a<=b)这个语句一开始不就是真值吗?为什么要这样比较?还有后面的:
                     /***使用Bresenham算法画圆**/     
                if(di<0)di +=4*a+6;          
                else
                {
                        di+=10+4*(a-b);   
                        b--;
                }
这样做的原理是为什么?

出0入0汤圆

发表于 2012-4-18 22:00:01 | 显示全部楼层
http://www.ourdev.cn/forum.php?m ... st%3D1%26digest%3D1

出0入0汤圆

发表于 2012-4-19 20:29:23 | 显示全部楼层
tdjsppwct 发表于 2012-4-18 17:21
你这个程序的原理是什么?看不明白啊!while(a

使用Bresenham算法画圆
我这不是标注了吗。。。

出0入0汤圆

发表于 2012-4-19 22:17:57 | 显示全部楼层
本帖最后由 tdjsppwct 于 2012-4-19 22:22 编辑
cqv 发表于 2012-4-19 20:29
使用Bresenham算法画圆
我这不是标注了吗。。。


di = 3 - 2 * r;    //判断下个点位置的标志
为什么要对di这样赋值?这个判断下一个点的原理是怎么判断的?没有懂

还有:if(di<0)     di +=4*a+6;         
         else          di+=10+4*(a-b);   
这个判断里面为什么di的值是这样计算的,实在不懂!查了下该算法,可是还是没有搞懂!望指点迷津,谢谢!

出0入0汤圆

发表于 2012-4-20 18:32:47 | 显示全部楼层
tdjsppwct 发表于 2012-4-19 22:17
di = 3 - 2 * r;    //判断下个点位置的标志
为什么要对di这样赋值?这个判断下一个点的原理是怎么判断的 ...

。。我也没深入过,我也是就拿来用。
你真要研究,去研究“计算机图形学”吧。

出0入0汤圆

发表于 2012-4-20 18:39:21 | 显示全部楼层
void disp_circle(uchar a,uchar b,uchar r,uint o)
{                            //a,b:圆心坐标  r:半径 o:圆心角
    uchar x,y;               //x,y:圆上坐标
    x=(uchar)(a-r*cos((double)(o*rad)));
    y=(uchar)(b-r*sin((double)(o*rad)));
    disp_dot(x,y);
}

void disp_dot(uchar hang,uchar lie)//hang:行(0~63)
{                                  //lie: 列(0~127)
    uchar col,page;                //col: 选择dot表中字形
    page=hang/8;                   //page:判断属于哪一页
    col=hang%8;
    set_page_address(7-page);
    set_col_address(lie);
    w_data(dot[col]);
}

出0入0汤圆

发表于 2012-4-21 07:38:28 | 显示全部楼层
cqv 发表于 2012-4-20 18:32
。。我也没深入过,我也是就拿来用。
你真要研究,去研究“计算机图形学”吧。 ...

谢谢,我慢慢研究吧

出0入0汤圆

发表于 2012-8-10 17:12:47 | 显示全部楼层
tdjsppwct 发表于 2012-4-21 07:38
谢谢,我慢慢研究吧

研究的咋样阿?我也想知道为什么阿

出0入0汤圆

发表于 2012-8-13 09:41:50 | 显示全部楼层
Ytu-xiaolizig 发表于 2012-8-10 17:12
研究的咋样阿?我也想知道为什么阿

一大堆烂事挤在一起了,哪有时间研究啊!

出0入0汤圆

发表于 2012-8-13 09:49:18 | 显示全部楼层
好帖子,以后能用到,MARK下,画圆函数讨论

出0入0汤圆

 楼主| 发表于 2012-8-13 11:35:56 | 显示全部楼层
这段时间由于开始上班了,回来都比较累。都没什么多余的精力去学习了。不过很是多谢大家的帮助

出0入0汤圆

发表于 2012-8-13 14:37:32 | 显示全部楼层
谢谢分享!!

出0入0汤圆

发表于 2014-6-20 16:55:10 | 显示全部楼层
学习了,试验成功!画的圆很圆!

出0入0汤圆

发表于 2014-6-20 17:24:12 | 显示全部楼层
受教了,
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 12:34

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表