依次计算围绕圆的点

Posted

技术标签:

【中文标题】依次计算围绕圆的点【英文标题】:Calculating points around a circle in sequence 【发布时间】:2012-06-13 18:18:59 【问题描述】:

我从一篇精彩的文章中改编了一些代码,该文章是 Mukund Sivaraman 绘制的关于圆绘制的文章,以便为给定圆上的每个点执行传递的函数:

template<class Function>
static void For_each_point_on_circle(Image *image, int radius, Function function)

    int x, y;
    int l;
    l = (int) radius * cos (M_PI / 4);
    for (x = 0; x <= l; x++)
    
        y = (int) sqrt ((double) (radius * radius) - (x * x));
        function(image, x, y);
        function(image, x, -y);
        function(image, -x, y);
        function(image, -x, -y);
        function(image, y, x);
        function(image, y, -x);
        function(image, -y, x);
        function(image, -y, -x);
  

但是,我真正需要的是按顺序计算圆周围的点,因此对 function(image, x, y) 的调用将从 0 到 360 度按顺序进行,而不是跳过,这是可以接受的画圆。

我可以计算所有点并对它们进行排序,但我希望有人知道一种正确的方法,也许使用多个循环,每个循环计算一个段?

非常感谢。

【问题讨论】:

圆上的点相距多远? (1度?) 彼此相距仅 1 个像素,不一定有任何固定度数。谢谢。 如果你想在均匀的空间中绕圆(即使是关于弧长,而不是 x 轴),我建议使用极坐标和 2*PI 的合适除法,基于多少您要绘制的点。 显而易见的function(image, radius*cos(angle), radius*sin(angle))有什么问题? @Danny:停留在像素坐标然后尝试进入极坐标更容易。角度像素间距在圆周围不是恒定的。如果你想计算它,它将是角度和分辨率的函数。 【参考方案1】:

应该这样做:

template<class Function>
static void For_each_point_on_circle(Image *image, int radius, Function function)

    int x, y;
    int l;
    l = (int) radius * cos (M_PI / 4);
    for (x = -l; x < l; x++)
    
        y = (int) sqrt ((double) (radius * radius) - (x * x));
        function(image, x, y);
    
    for (x = -l; x < l; x++)
    
        y = (int) sqrt ((double) (radius * radius) - (x * x));
        function(image, y, -x);
    
    for (x = -l; x < l; x++)
    
        y = (int) sqrt ((double) (radius * radius) - (x * x));
        function(image, -x, -y);
    
    for (x = -l; x < l; x++)
    
        y = (int) sqrt ((double) (radius * radius) - (x * x));
        function(image, -y, x);
    

【讨论】:

这非常接近,它会产生以下输出:i.imgur.com/XIGWy.png。我会努力填补这些漏洞,我现在应该没事了。完成后,我将使用完整代码更新主帖。感谢大家的帮助! @user1454345 - 这是我在上面的 cmets 中得到的。半径越大,这个问题就越严重。 @atb - 没关系,我在计算 l 时错过了 cos (M_PI / 4) 因子。虽然这有助于将其分解为 4 个循环,但并不能真正解决问题。随着半径的增加,最终它会变得足够大,以至于在一个象限内,相邻的 x 值将映射到不相邻的 y 值。我认为解决它的唯一方法是为每个 x 值计算像素,并为范围内的每个 y 值分别计算像素。 它似乎确实适用于我尝试过的半径值imgur.com/aRyC8。 - 渐变显示像素的绘制顺序。 @atb - 你是对的,它的工作原理是半径 * 半径太大。【参考方案2】:

这是一篇关于分步走圆的文章。它的动机是用于 CNC 机器步进电机控制器,但也许它可以满足您的目的。

https://github.com/Falmarri/cnc/blob/master/BresenHam-3D-helix.pdf

【讨论】:

以上是关于依次计算围绕圆的点的主要内容,如果未能解决你的问题,请参考以下文章

使用来自两个自旋向量的点在球体上插值 x、y、z 坐标?

计算沿预定义线串从线串开始到围绕该线串的缓冲区域内的点的路线长度

2017多校第6场 HDU 6097 Mindis 计算几何,圆的反演

最小覆盖圆的神奇算法及例题

围绕另一个点旋转一个点

如何用C语言计算圆的周长和面积