当前位置: 首页 > 面试题库 >

带厚度绘图的圆算法

宗弘扬
2023-03-14
问题内容

目前,我正在使用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:我不想使用任何外部库!


问题答案:

如果按照中点圆算法的说明沿着八分圆进行扫描,则主坐标y将始终增加一。然后,您可以一次绘制两个圆,因为它们的主要坐标是同步的。

不用放置像素,而是在具有相同y(或x)坐标的内圆和外圆点之间绘制水平(和垂直)线。直到外圆到达对角线为止。

您保持与国家xerr两个圈,内圈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, yc + y,  colour);
        yLine(xc + y,  yc + xi, yc + xo, colour);
        xLine(xc - xo, xc - xi, yc + y,  colour);
        yLine(xc - y,  yc + xi, yc + xo, colour);
        xLine(xc - xo, xc - xi, yc - y,  colour);
        yLine(xc - y,  yc - xo, yc - xi, colour);
        xLine(xc + xi, xc + xo, yc - y,  colour);
        yLine(xc + y,  yc - xo, yc - 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);
            }
        }
    }
}


 类似资料:
  • 目前我正在使用Bresenham的圆圈绘制算法,它可以精细地绘制圆圈,但是我想要一种相对快速有效的方法来绘制具有指定厚度的圆圈(因为Bresenham的方法只绘制单个像素厚度)。我意识到我可以简单地绘制多个具有不同半径的圆圈,但我相信这将是非常低效的(并且效率很重要,因为这将在每微秒都很宝贵的Arduino上运行)。我目前使用以下代码: 我如何修改它以允许指定圆的厚度?PS我不想使用任何外部库,请

  • 我已经写了一个Bresenham的圆绘制算法的实现。该算法利用了圆的高度对称特性(它只计算第一个八分之一的点,并利用对称性绘制其他点)。因此,我希望它会非常快。《图形编程黑皮书》第35章的标题是“Bresenham是快的,而且快是好的”,虽然它是关于线条绘制算法的,但我可以合理地预期圆形绘制算法也很快(因为原理是一样的)。 这是我的java,摇摆实现 此方法使用以下方法: getNativeX和g

  • 如何更改散点图中标记线的粗细?是中的有效属性;图是否有等价属性? 我不是想改变尺寸而是线条粗细!

  • 我想在不显示直方图的情况下绘制密度线,我使用了以下代码:

  • 本文向大家介绍Android带进度的圆形进度条,包括了Android带进度的圆形进度条的使用技巧和注意事项,需要的朋友参考一下 我们还是用一个小例子来看看自定义View和自定义属性的使用,带大家来自己定义一个带进度的圆形进度条,我们还是先看一下效果吧 从上面可以看出,我们可以自定义圆环的颜色,圆环进度的颜色,是否显示进度的百分比,进度百分比的颜色,以及进度是实心还是空心等等,这样子是不是很多元化很

  • 我有一个加载了位图的ImageView。当用户触摸位图时,我使用画布在位图上的触摸位置绘制一个圆。现在,我需要撤消绘制的圆。在任何地方,我都能找到一些片段来撤销绘制的路径,而不是直接撤销一个圆。有人有办法撤消先前绘制的圆吗?

  • 本文向大家介绍Android编程绘制圆形图片的方法,包括了Android编程绘制圆形图片的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Android编程绘制圆形图片的方法。分享给大家供大家参考,具体如下: 效果图如下: 第一步:新建RoundView自定义控件继承View 第二步 新建布局文件Activity_main.xml 运行! 更多关于Android相关内容感兴趣的读者可查

  • 我只是试图用DrawOval()方法画圆,当我运行程序时,它只显示小正方形。我试图将构造函数添加到Surface类,但它不起作用。这是我制作的代码: