加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

圆形厚度绘制算法

发布时间:2020-12-16 07:10:36 所属栏目:百科 来源:网络整理
导读:目前我正在使用Bresenham的圆绘制算法,它可以精确地绘制圆圈,但是我想要一种相对快速有效的方法来绘制具有指定厚度的圆(因为Bresenham的方法只绘制单个像素厚度).我意识到我可以简单地绘制具有不同半径的多个圆圈,但我相信这将是非常低效的(并且效率很重要因
目前我正在使用Bresenham的圆绘制算法,它可以精确地绘制圆圈,但是我想要一种相对快速有效的方法来绘制具有指定厚度的圆(因为Bresenham的方法只绘制单个像素厚度).我意识到我可以简单地绘制具有不同半径的多个圆圈,但我相信这将是非常低效的(并且效率很重要因为这将在Arduino上运行,其中每微秒都是宝贵的).
我目前正在使用以下代码:

void circle(byte xc,byte yc,int radius,Colour colour) {
  int x = -radius,y = 0,err = 2 - 2 * radius;
  while(x < 0) {
    setPixel(xc - x,yc + y,colour);
    setPixel(xc - y,yc - x,colour);
    setPixel(xc + x,yc - y,colour);
    setPixel(xc + y,yc + x,colour);
    radius = err;
    if(radius <= y) {
      err += ++y * 2 + 1;
    }
    if(radius > x || err > y) {
      err += ++x * 2 + 1;
    }
  }
}

我怎么能修改它以允许指定圆的厚度?
PS我不想使用任何外部库,请!

解决方法

如果按照 Midpoint circle algorithm的说明扫描八分圆,则主坐标y将始终增加1.然后,您可以一次绘制两个圆,因为它们的主坐标是同步的.

您可以在内圈和外圈的点之间绘制水平(和垂直)线,而不是放置像素,这些线具有相同的y(或x)坐标.这样做直到外圆到达对角线.

你保持状态x和错误两个圆,内圈i和外圈o.在内圆到达对角线后,内点位于该对角线上.这意味着您要绘制八个相邻的八分圆扇区.

这个想法与@oakad在评论中提出的非常类似,但不需要保留列表.中点圆算法可能比Bresenham算法慢,因此可能还有改进的余地,但内存占用率低是一个优势.

下面的代码将绘制一个具有给定内半径和外半径的空心圆.线宽为ro-ri 1,因此即使相等的半径也会打印出一个像素宽的圆.如果内半径小于外半径,则不会打印任何内容.

void xLine(int x1,int x2,int y,int colour)
{
    while (x1 <= x2) setPixel(x1++,y,colour);
}

void yLine(int x,int y1,int y2,int colour)
{
    while (y1 <= y2) setPixel(x,y1++,colour);
}

void circle2(int xc,int yc,int inner,int outer,int colour)
{
    int xo = outer;
    int xi = inner;
    int y = 0;
    int erro = 1 - xo;
    int erri = 1 - xi;

    while(xo >= y) {
        xLine(xc + xi,xc + xo,colour);
        yLine(xc + y,yc + xi,yc + xo,colour);
        xLine(xc - xo,xc - xi,colour);
        yLine(xc - y,yc - xo,yc - xi,colour);
        xLine(xc + xi,colour);

        y++;

        if (erro < 0) {
            erro += 2 * y + 1;
        } else {
            xo--;
            erro += 2 * (y - xo + 1);
        }

        if (y > inner) {
            xi = y;
        } else {
            if (erri < 0) {
                erri += 2 * y + 1;
            } else {
                xi--;
                erri += 2 * (y - xi + 1);
            }
        }
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读