计算方形内的列宽以控制圆周上的项目距离

时间:2014-10-24 14:08:07

标签: algorithm

我努力表达这个问题,所以我会尽力而为,并且随着我的理解的改善而清理它。

我们假设我们有一个通过线条划分为垂直线段的正方形。在我们的广场内,我们还有一个非常适合的圆圈。

在每个垂直线段内,我放置一个直接位于圆周上的物品。

是否有一种算法可以定义每个段必须具有的宽度,以便每个段中的项目坐在圆周上,彼此之间的距离也相等?

这是我对场景的惊人白板草图:

enter image description here

1 个答案:

答案 0 :(得分:2)

我希望你有这样的想法。

enter image description here

这是使用下面描述的数学生成上图的Python。

#!/usr/bin/env python3
import math
import sys


def layout(n):
    assert isinstance(n, int)
    assert n >= 1
    divisions = [0.0] * (n + 1)
    divisions[0] = -1.0
    divisions[n] = 1.0
    for i in range(1, (n + 1) // 2):
        box = -math.cos(i / (n + 1) * math.pi)
        divisions[i] = 2.0 * box - divisions[i - 1]
        divisions[n - i] = -divisions[i]
    return divisions


def quality(divisions):
    n = len(divisions) - 1
    boxes = [0.5 * (divisions[i] + divisions[i + 1]) for i in range(n)]
    angles = [math.asin(box) for box in boxes]
    differences = [angles[i] - angles[i + 1] for i in range(n - 1)]
    return max(differences) - min(differences)


def eps(divisions):
    n = len(divisions) - 1
    print('%!PS-Adobe-3.0 EPSF-3.0')
    print('%%BoundingBox: 0 0 216 216')
    print('0.008 setlinewidth')
    print('108 108 translate')
    print('90 90 scale')
    print('newpath 1 1 moveto -1 1 lineto -1 -1 lineto 1 -1 lineto closepath stroke')
    print('newpath 0 0 1 0 360 arc closepath stroke')
    for i in range(n):
        x = 0.5 * (divisions[i] + divisions[i + 1])
        print('newpath {} {} moveto 0.05 0.05 rmoveto -0.1 0 rlineto 0 -0.1 rlineto 0.1 0 rlineto 0 0.1 closepath fill'.format(x, math.sqrt(1 - x ** 2)))
    print('[0.016 0.016] 0 setdash')
    for i in range(1, n):
        print('newpath {} 1 moveto 0 -2 rlineto stroke'.format(divisions[i]))


if __name__ == '__main__':
    eps(layout(11))
    for m in range(2, 12):
        print(quality(layout(m)), file=sys.stderr)

假设标准数学坐标如此。

         +y
          ^
          |
   (-1,1) | (1,1)
         +-+
-x <-----|O|-----> +x
         +-+
  (-1,-1) | (1,-1)
          |
          v
         -y

由于盒子应该在圆圈上具有等距的中心,因此这些中心应该以规则的间隔具有角度。角度θ(以弧度表示)的点为(cos θ, sin θ)。圆圈顶部为θ = π/2,因此示例中的角度可能是(从左到右)11π/12, 3π/4, 7π/12, 5π/12, π/4, π/12(间隔为-π/6)。

让这些点的x坐标为b(1) ≤ b(2) ≤ ... ≤ b(n)b为框)。我们希望找到分隔符位置d(1) ≤ d(2) ≤ ... ≤ d(n-1),使每个框位于两个相邻分隔符的中点,即

       d(0) + d(1)
b(1) = -----------
            2

       d(1) + d(2)
b(2) = -----------
            2

...

       d(n-1) + d(n)
b(n) = ------------- ,
             2

其中d(0) = -1d(n) = 1是该框的边缘。

这是n变量中的n-1方程组。对于b(i)的一般值,此系统将没有解决方案。幸运的是,可以展示可以实现的b(i)的特定选择。

b(i) = -cos((i/(n+1)) pi)