在以任意角度旋转后,如何在X轴上找到多边形的最小投影?

时间:2013-11-06 08:05:40

标签: c++ algorithm rotation geometry computational-geometry

考虑到2D多边形的顶点,我必须在X轴上找到多边形的最小可能投影。

我被允许以任意角度旋转多边形。

首先我想到了最小的情况,至少有一个多边形的边将与X轴对齐,但事实并非如此。

多边形可以是凹面或凸面。

3 个答案:

答案 0 :(得分:6)

您正在寻找的是“旋转卡尺算法”。

https://en.wikipedia.org/wiki/Rotating_calipers

关于此算法的维基百科页面甚至为您的问题提供了伪代码。

https://en.wikipedia.org/wiki/Rotating_calipers#Minimum_width_of_a_convex_polygon

答案 1 :(得分:2)

如评论中所述,如果用凸包替换多边形,答案将不会发生变化。所以我们认为多边形已经是凸的。现在假设我们找到了最小角度。这意味着我们有一条平行于Y的条带限制身体。很容易看出多边形边之一可以位于条带边界上(如果不是,我们可以稍微旋转主体而不增加条带宽度)。

总结一下,我们得到一个算法:计算凸包,然后为船体的每一侧选择一个角度,使其与Y平行并测试宽度。拿分钟。 0

答案 2 :(得分:0)

设X(i,alpha)为旋转角度α后的顶点i的X- coodrinate。

我们总是假设-PI< = alpha< = PI。

如果X(i,alpha)> = X(j,alpha),则对于所有j,令i =最右边(alpha)。如果除了一个之外的所有j,则i = second_rightmost(alpha),如果X(i,alpha)> = X(j,alpha)。类似地定义leftmost()和second_leftmost()。

让我们证明以下内容:如果X(i,α)> = X(j,α),并且X(i,β)> = X(j,β),并且β-α<1。对于[α,β]中的所有γ,PI,然后X(i,γ)> = X(j,γ)。实际上,X(i,alpha)= x [i] * cos(alpha)-y [i] * sin(alpha),其中(x [i],y [i])是顶点i的初始位置。因此,X(i,a)-X(j,a)= c1 * cos(a)-c2 * sin(a),其中c1 = x [i] -x [j],c2 = y [i] - Y [j]的。设f(a)= X(i,a)-Y(i,a)。函数f是连续的,并且当tan(a)= c1 / c2时改变其符号,即a = atan2(c1,c2)+ PI * n。如果是beta-alpha

现在我们有:

  • 如果最右边(alpha)=最右边(beta)和beta-alpha&lt; PI,然后最右边(x)=最右边(alpha)所有alpha&lt; x&lt;测试
  • 如果i =最右边(alpha)= second_rightmost(beta),并且j =最右边(beta)= second_rightmost(alpha),并且beta-alpha&lt; PI,然后对于alpha和beta之间的所有x,rightnost(x)是i或j,并且变化点是atan2(y [i] -y [j],x [i] -x [j])。

这足以通过二进制搜索获得哪个点是最右边的间隔。通过角度的符号反转,我们得到最左边的点间隔。由于我们知道每个点最左边的哪个间隔,并且每个点都是最右边的,我们可以计算间隔之间边界处的值,并选择最小值。