【问题标题】:create a circular list by using a range of angles python通过使用一系列角度python创建一个圆形列表
【发布时间】:2017-02-09 10:03:10
【问题描述】:

我有一个列表列表,其中包含角度集的下限和上限

类似

[[1,22],[2,24]...[359,15],[360,21]]

总共 360 个元素

现在我想检查从 1 到 360 的每个角度列表中包含该角度的元素

我正在考虑使用下限和上限来使用rangenp.arange(lower,upper) 创建列表的所有元素并检查是否包含角度,但是np.arange 在下限高于上限时生成空列表

for i in range(1,361):
    sel=[]
    for coe in coef:
        if i in range(coe[0],coe[1]):
            sel.append(coe)

我也尝试了itertoolscycle,但我不知道在这种情况下如何应用它

【问题讨论】:

  • 如果循环遍历所有可能的角度,所有元素最终不会包含在 sel 中吗?

标签: python range circular-list


【解决方案1】:

执行此操作的标准方法是使用模数。 sschuberth 的This answer 展示了如何在 C/C++ 中执行此操作。

这是一个 Python 实现和测试。 Python 中的代码更简单,因为在 Python 中 a % b 始终与 b 具有相同的符号。

对于ab,测试代码以 60 的步长循环从 0 到 360 度的所有角度对,以 30 的步长测试从 0 到 360 度的所有角度 x。扇区开始在a 并扫过b。因此扇区 (60, 120) 包含 60°,但 (120, 60) 包含 300°。

如果x 在扇区内(包括端点),它将被添加到result 列表中。

def in_angle_interval(x, a, b):
    return (x - a) % 360 <= (b - a) % 360

# test 

for a in range(0, 420, 60):
    for b in range(0, 420, 60):
        result = [x for x in range(0, 390, 30) if in_angle_interval(x, a, b)]
        print('{:3}-{:3} {}'.format(a, b, result))

输出

  0-  0 [0, 360]
  0- 60 [0, 30, 60, 360]
  0-120 [0, 30, 60, 90, 120, 360]
  0-180 [0, 30, 60, 90, 120, 150, 180, 360]
  0-240 [0, 30, 60, 90, 120, 150, 180, 210, 240, 360]
  0-300 [0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 360]
  0-360 [0, 360]
 60-  0 [0, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330, 360]
 60- 60 [60]
 60-120 [60, 90, 120]
 60-180 [60, 90, 120, 150, 180]
 60-240 [60, 90, 120, 150, 180, 210, 240]
 60-300 [60, 90, 120, 150, 180, 210, 240, 270, 300]
 60-360 [0, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330, 360]
120-  0 [0, 120, 150, 180, 210, 240, 270, 300, 330, 360]
120- 60 [0, 30, 60, 120, 150, 180, 210, 240, 270, 300, 330, 360]
120-120 [120]
120-180 [120, 150, 180]
120-240 [120, 150, 180, 210, 240]
120-300 [120, 150, 180, 210, 240, 270, 300]
120-360 [0, 120, 150, 180, 210, 240, 270, 300, 330, 360]
180-  0 [0, 180, 210, 240, 270, 300, 330, 360]
180- 60 [0, 30, 60, 180, 210, 240, 270, 300, 330, 360]
180-120 [0, 30, 60, 90, 120, 180, 210, 240, 270, 300, 330, 360]
180-180 [180]
180-240 [180, 210, 240]
180-300 [180, 210, 240, 270, 300]
180-360 [0, 180, 210, 240, 270, 300, 330, 360]
240-  0 [0, 240, 270, 300, 330, 360]
240- 60 [0, 30, 60, 240, 270, 300, 330, 360]
240-120 [0, 30, 60, 90, 120, 240, 270, 300, 330, 360]
240-180 [0, 30, 60, 90, 120, 150, 180, 240, 270, 300, 330, 360]
240-240 [240]
240-300 [240, 270, 300]
240-360 [0, 240, 270, 300, 330, 360]
300-  0 [0, 300, 330, 360]
300- 60 [0, 30, 60, 300, 330, 360]
300-120 [0, 30, 60, 90, 120, 300, 330, 360]
300-180 [0, 30, 60, 90, 120, 150, 180, 300, 330, 360]
300-240 [0, 30, 60, 90, 120, 150, 180, 210, 240, 300, 330, 360]
300-300 [300]
300-360 [0, 300, 330, 360]
360-  0 [0, 360]
360- 60 [0, 30, 60, 360]
360-120 [0, 30, 60, 90, 120, 360]
360-180 [0, 30, 60, 90, 120, 150, 180, 360]
360-240 [0, 30, 60, 90, 120, 150, 180, 210, 240, 360]
360-300 [0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 360]
360-360 [0, 360]

这是使用问题中的数据进行的测试。

coef = [[1,22], [2,24], [359,15], [360,21]]
print(coef)
for x in range(0, 361):
    sel = [coe for coe in coef if in_angle_interval(x, coe[0], coe[1])]
    if sel:
        print('{:3} {}'.format(x, sel))

输出

[[1, 22], [2, 24], [359, 15], [360, 21]]
  0 [[359, 15], [360, 21]]
  1 [[1, 22], [359, 15], [360, 21]]
  2 [[1, 22], [2, 24], [359, 15], [360, 21]]
  3 [[1, 22], [2, 24], [359, 15], [360, 21]]
  4 [[1, 22], [2, 24], [359, 15], [360, 21]]
  5 [[1, 22], [2, 24], [359, 15], [360, 21]]
  6 [[1, 22], [2, 24], [359, 15], [360, 21]]
  7 [[1, 22], [2, 24], [359, 15], [360, 21]]
  8 [[1, 22], [2, 24], [359, 15], [360, 21]]
  9 [[1, 22], [2, 24], [359, 15], [360, 21]]
 10 [[1, 22], [2, 24], [359, 15], [360, 21]]
 11 [[1, 22], [2, 24], [359, 15], [360, 21]]
 12 [[1, 22], [2, 24], [359, 15], [360, 21]]
 13 [[1, 22], [2, 24], [359, 15], [360, 21]]
 14 [[1, 22], [2, 24], [359, 15], [360, 21]]
 15 [[1, 22], [2, 24], [359, 15], [360, 21]]
 16 [[1, 22], [2, 24], [360, 21]]
 17 [[1, 22], [2, 24], [360, 21]]
 18 [[1, 22], [2, 24], [360, 21]]
 19 [[1, 22], [2, 24], [360, 21]]
 20 [[1, 22], [2, 24], [360, 21]]
 21 [[1, 22], [2, 24], [360, 21]]
 22 [[1, 22], [2, 24]]
 23 [[2, 24]]
 24 [[2, 24]]
359 [[359, 15]]
360 [[359, 15], [360, 21]]

【讨论】:

    【解决方案2】:

    也许使用自定义的比较功能?

        def compare(angle, lower, upper):
            if lower <= upper:
                return lower <= angle and angle <= upper
            else:
                return ((angle >= lower and angle <= 360)
                        or (angle <= upper and angle >= 1))
    

    然后测试角度是否在任何区间内:

        >>> angle
        3
        >>> intervals
        [[1,22],[2,24]...[359,15],[360,21]]
        >>> any([compare(angle, *interval) for interval in intervals])
        True
    

    【讨论】:

      猜你喜欢
      • 2015-05-06
      • 1970-01-01
      • 2014-09-25
      • 2021-01-16
      • 2016-06-02
      • 2023-04-04
      • 1970-01-01
      • 2018-09-18
      • 1970-01-01
      相关资源
      最近更新 更多