计算多边形的边数


18

计算多边形的边数

多边形计数机器人已决定在不通知任何人的情况下环游​​世界,但至关重要的是,多边形计数的过程不要停留太长时间。因此,您需要执行以下任务:给定多边形的黑白图像,您的程序/ Funtoin应该返回边数。

该程序将被送入一台旧的打孔卡计算机,并且由于当今的打孔卡非常昂贵,因此您最好尝试使程序尽可能短。

边缘的长度至少为10个像素,并且两个相邻边缘形成的角度至少为10°但不大于170°(或再次大于190°)。该多边形图像中完全包含和多边形,以及它的补连接(没有孤立的岛屿),所以这个投入将不会是有效的:

在此处输入图片说明

计分

这是代码高尔夫,这意味着以字节为单位的最短提交胜出,您的提交必须为每个测试用例找到正确的边数。(提交也应适用于其他情况,不允许仅针对那些测试用例进行优化。)

如果您希望提交的解决方案每次都找不到正确的编号,您也可以提交该解决方案,但是它将在所有性能更好的提交中排在后面。

请在提交标题中包括总数。(总误差为实际边数与每个输出之间的绝对差之和)。

测试用例

n = 10

在此处输入图片说明在此处输入图片说明

n = 36

在此处输入图片说明在此处输入图片说明

n = 7

在此处输入图片说明在此处输入图片说明

n = 5

在此处输入图片说明在此处输入图片说明

这不是一个测试用例,只是出于好奇:您为该输入获得了多少优势?

在此处输入图片说明


我在您的测试案例中看到许多大于170°的角度。例如,恒星中所有“非点”角度(更靠近中心的角度)。
门把手

@门把手较小的角度应小于170°。
lirtosiast 2015年

是的,但它们又大于190°。该限制的目的是消除两个相邻边难以区分的示例。
flawr

2
多边形的内部是哪种颜色?
feersum 2015年

1
该程序将被送入一台旧的打孔卡计算机,并且由于如今的打孔卡非常昂贵,因此您最好尽量缩短程序的时间:-)
Luis Mendo

Answers:


12

Python 2 + PIL,没有错误, 313 307字节

from Image import*
I=open(sys.argv[1])
w,h=I.size;D=I.getdata()
B={i%w+i/w*1j for i in range(w*h)if D[i]!=D[0]}
n=d=1;o=v=q=p=max(B,key=abs)
while p-w:
 p+=d*1j;e=2*({p}<B)+({p+d}<B)
 if e!=2:e%=2;d*=1j-e*2j;p-=d/1j**e
 if abs(p-q)>5:
    t=(q-v)*(p-q).conjugate();q=p;w=o
    if.98*abs(t)>t.real:n+=1;v=p
print n

在命令行上获取图像文件名,然后将结果打印到STDOUT。

给出所有测试的正确结果,圆的n = 28。

说明

该算法的工作原理是沿着多边形的周界走动,然后计算遇到的顶点数量(检测为方向变化)。我们从距原点最远的像素开始,该像素o保证是顶点,因此与边缘(即,前景像素和背景像素之间的边界)相邻。我们会跟踪位置,p最近的顶点v和最新的“检查点” q,所有这些初始都等于o。我们还跟踪d相对于当前像素的边缘方向;d最初指向东边,这是一个安全的方向,因为我们知道东边有一条边o,否则它离原点就不会最远。我们沿着边缘,在垂直于的方向上移动d,从而d指向我们的左侧,即顺时针方向。每当我们“掉落边缘”时,即在p多边形外部或左侧像素(即方向d)上位于多边形内部的任何情况下,我们都会进行调整pd相应地进行恢复。

每当p最后一个检查点之间的距离q大于5时,我们都会尝试确定是否在q和之间的顶点上通过p:我们比较之间的角度vq(即,从v到的向量q),即角度的大致方向。当到达最后一个检查点时,我们沿着多边形的另一侧行走qp,最后一个检查点与当前位置之间的位移。如果该角度大于大约10°,则可以得出结论,我们正在沿着多边形的另一侧行走,增加了顶点数量,并将v当前顶点设置为p。在每个检查点,无论是否检测到顶点,我们都q将最后一个检查点更新为p。我们以这种方式继续,直到返回o到起点为止,然后返回找到的顶点数量(请注意,顶点计数最初为1,因为起点o本身就是一个顶点。)

下图显示了检测到的顶点。请注意,p由于新顶点的位置不是最优的,因此将每个检查点的当前位置作为最优值,因为实际顶点可能位于沿周长的最后一个检查点q和之间p。如您所见,除第一个顶点(通常是右下角顶点)以外的所有顶点都略有偏离。修复此问题将花费更多的字节,但这似乎已经足够好了。话虽这么说,要仅用四个测试用例就很难适应。

n = 10 n = 36 n = 7 n = 5 圈


感谢您的详细解释!我爱你的插图!
flawr

如果在的东边有一条边o,那么另一端会离原点更远吗?
aditsu

1
@aditsu我认为这里的术语可能有些混乱。我们谈论以几何图形的形式多边形以及多边形的(包括该像素的像素集)边缘o是离原点最远的前景像素,因此东边的像素必须是背景像素,因此我们说的东边有一条边o
Ell
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.