如何将标记转换为具有最小线交叉点的半圆?

How to translate markers into a half circle with minimal line intersection?

我有一张地图,上面显示了很多标记。有时标记彼此非常接近以至于它们重叠。为了解决这个问题,我实现了一个 spiderfier 库来解决这个问题。

我们的想法是将屏幕上足够靠近的标记分组(在数学上向下),这样它们就不会相互交叉。

标记显示为矩形。

实施:

到目前为止,还不错。

问题:这些线彼此相交的频率太高,我们需要一个比较器函数来最小化标记线相交的数量。

尝试次数:

  1. P1.x <= P2.x => P1 <= P2

  2. arctan((P1.y - C.y) / (R * (P1.x - C.x))) <= arctan((P2.y - C.y) / (R * (P2.x - C.x))) => P1 <= P2

我对第二次尝试寄予厚望,但不得不承认这不是一个好主意,因为平移线和实际位置与圆心之间的线不一定共线,在实际上,如果有许多标记的真实位置彼此非常接近,则它们的角度会变得相当大,而半圆的表面除了这个子区域之外是相当贫瘠的。因此,这也会导致交叉点,并且比第一次尝试复杂得多。我相信Javascript的Math.atan is implemented either with Taylor series or Fourier series,它在第一种情况下涉及导数,在第二种情况下涉及积分。或者,可能还有第三种方法,它也非常复杂。如果第二种方法可以显着减少交叉点的数量,我会考虑优化和类似的东西,但由于这种改进几乎看不到,所以我回到了第一种方法。

我正在考虑以下方法:

这个想法是否会导致蜘蛛线交叉点数量最小化的状态,如果不是,我如何才能最小化此类交叉点的数量?

这是一道难题,研究了很久。 它有时被称为 automatic label placement。 下面引用的工作是文献中可用的典型工作。



Van Kreveld, Marc, Tycho Strijk, and Alexander Wolff. "Point set labeling with sliding labels." Proceedings of the fourteenth annual symposium on Computational geometry. ACM, 1998. ACM link.