我正在努力为我解决一个非常棘手的问题。我不是编程的新手,但我真的不知道如何找出这个问题。它给出了一组以Xi和Yi坐标作为输入的点(point [])。该程序必须输出多边形的凸包的周长,但如果有必要,它可以将船体分成两部分,两个单独的凸包,每个将包含多个点。这种划分的目标是使周长更短(如果这两个船体的周长之和短于一个船体的周长;例如:两个远离彼此的点集群)。问题还在于船体不能超过两个。我很感激任何想法。
这个问题有一个简单的例子(可能还有很多要点)。在这里你可以看到两个分开的船体的周长比一个周长短。
ADD:实际上,“周长”是指周长。
这是我的代码的关键部分:
m.x = (a.x + b.x)/2;
m.y = (a.y + b.y)/2;
ab.first = b.x - a.x;
ab.second = b.y - a.y;
for (i=0; i<n; ++i)
{
if (p[i].x * ab.first + p[i].y * ab.second - (SQ(ab.second) + SQ(ab.first))/2 > 0)
left[l++]=p[i];
else if (p[i].x * ab.first + p[i].y * ab.second - (SQ(ab.second) + SQ(ab.first))/2 < 0)
right[r++]=p[i];
if (p[i].x * ab.first + p[i].y * ab.second - (SQ(ab.second) + SQ(ab.first))/2 == 0)
mid[md++]=p[i];
}
答案 0 :(得分:4)
当存在两个(或更多个)长分离的星团时,似乎两个船体将是有益的。所以我建议尝试一种简单的方法(可能是近似的):
construct convex hull
find the farthest pair of points (A, B) in hull with rotating calipers
divide all the points with middle perpendicular to AB segment
find hulls of resulted clouds and calculate profit or loss
已添加: finding the farthest pair of points with rotating calipers link
已添加2:如何将点云划分为中间垂直:
中点:M =(A + B)/ 2
(M.X =(A.X + B.X)/ 2,M.Y =(A.Y + B.Y)/ 2)
AB载体:(B.X-A.X,B.Y-A.Y)
中间垂直线有一般方程式:
(y-M.Y) / AB.X = - (x-M.X) / AB.Y
(y-M.Y) * AB.Y + (x-M.X) * AB.X = 0
//incorrect x * AB.X + y * AB.Y - (AB.Y^2 + AB.X^2)/2 = 0
x * AB.X + y * AB.Y - (B.Y^2 - A.Y^2 + B.X^2 - A.X^2)/2 = 0
当你使用P [i] .X和P [i] .Y代替最后一个等式中的x和y in时,你会得到左边的点的正值,以及点的负值。线的右边(线上点的零值)
答案 1 :(得分:0)
我同意MBo的说法,就是要找到一个宽阔的间距来切割两个船体。但我不同意旋转卡钳是正确的方法。你关心的不是外部尺寸,而是内部尺寸。如果你有一组非常宽的点组成两条平行的水平线,你想要在两条线之间切割,而不是在每条线的中间切割。
基本上,我认为你想找到一条“厚”的分离线,它将点集切成两块,尽可能远离两边的点。这被称为“最远的超平面问题”,通常用于支持向量机算法的无监督变体。
这是一个很难(NP难)的问题,但有一些近似算法。基本思想是为线条采取许多潜在角度,并找出放置该角度线的位置以最大化其分离。