找到位于大多数角度间隔中的角度

Finding the angle which is located in most intervals of angles

本文关键字:大多数      更新时间:2023-10-16

我有角度区间(以弧度为单位)[0,2π)

  • 例如区间 [(2π)/3,(3π)/4]、[π/2,π] 等。
  • 但也可能有间隔 [(3π)/2,π/3]

我必须找到位于大多数间隔的角度。 在C++找到它的最佳方式是什么? 如何表示角度间隔?

您可以实现一个简单的扫描线算法来解决此问题。

对于每个区间,将区间的开始和结束添加到向量中;对此向量进行排序,然后遍历它。如果您有任何跨越 2π 边界的区间,只需将其拆分为两个区间,它们都在 (0, 2π) 内。

当您遍历列表时,请跟踪当前点有多少重叠迭代,以及到目前为止您看到的最佳角度(以及在该角度重叠的间隔数)。到达终点后,您就知道最佳角度是什么。

如果您需要多个角度,您可以相当轻松地调整此方法以记住具有最大重叠的间隔,而不是单个角度。

我会通过将 [0, 2π] 的分区维护为对应于间隔覆盖率的范围来做到这一点,每个范围都有一个计数。首先,以下是算法在没有任何区间超过 0(或 2π)的条件下的工作方式。还假设间隔按如下方式归一化:如果间隔以 0 结束,则更改为以 2π 结束;如果从 2π 开始,则更改为从 0 开始。

  1. 创建(范围,计数)对的列表,使用单个范围 [0, 2π] 和计数 0 进行初始化。(列表将按范围的开头排序。列表中的范围只会在其端点处重叠,并且始终覆盖 [0, 2π])。
  2. 按如下所述处理每个间隔
  3. 扫描列表中具有最高计数的(范围,计数)对。任意解决关系。返回范围内的任意角度。

要处理间隔i

  1. 找到i.start >= s.range.start的第一个(范围,计数)对(称为s)(即范围包含i.start)。(请注意,如果i.start是一个范围的结束,那么它将是另一个范围的开始;这将选择它是其开始的对。
  2. 查找i.end <= e.range.end的最后一个(范围、计数)对e。(请注意,如果i.end是一个范围的开始,那么它将是另一个范围的结束;这将选择它是结束的对。
  3. 如果i.start > s.range.start(i.ranges的内部开始),s分成两对(范围,计数)s1 = ([s.range.start, i.start], s.count)s2 = ([i.start, s.range.end], s.count)。将列表中的s替换为s1s2(按该顺序)。
  4. 如果i.end < e.range.end,则以与上一步平行的方式替换e,使用i.end进行拆分。
  5. 对于从s(如果s在步骤 3 中拆分,则为s2)到并包括e(如果e在步骤 4 中拆分,则e1)的每一对,计数加 1。

如果您不关心跟踪包含特定角度的实际间隔数,只是因为它是最大值,那么跨 0(或 2π)的间隔的簿记更容易:只需取区间的补码(反转开始和结束)并从步骤 5 中的计数中减去一个而不是相加。如果您确实需要绝对计数,请执行补码技巧,然后将 1 添加到列表中的每个计数中。

以上不会正确处理相邻的区间(例如:[0, π/3] 和 [π/3, π];或 [2π/3, 2π] 和 [0, 1])。在这些情况下,据我了解,它们相邻的角度(π/3 或 0)应该算作两个间隔。可以调整上述算法,以便当间隔开始与范围终点重合时,在相关对之后插入一个新的(范围,计数)对;新对将具有单角度范围(即range.start == range.end)。类似的过程将适用于从间隔结束时开始的范围。我认为通过这些调整,上述算法可以正确处理所有情况。

我的解决方案将涉及间隔开始的对列表以及有多少间隔重叠:

1        2       3       2              1
|---------|--------|-----|---------------|------|
|------------------|
|--------------|
|---------------------|
|----------------------------|

因此,对所有起点和终点进行排序,并遍历列表,为每个新间隔分配与其重叠的间隔计数(如果是起点,则增加它,否则减少)。然后从重叠计数中获取最大值。

我认为如果你不象征性地这样做,你会遇到奇怪的边缘情况。

您的角度范围不仅不能完全表示为二进制分数(引入舍入误差),而且是无理的。 (Pi大于 3.14159265359 但小于 3.14159265360;除了符号之外,你怎么说角度等于Pi/2?)

我认为最可靠的方法是依次获取所有区间组合,确定它们的交集,并查看这些组合区间中的哪些是大多数单个区间的交集的结果。

这也有一个好处,即为您提供的不仅仅是一个,而是满足您条件的所有角度。