我有一个形状(下面是黑色)和形状内的一个点(下面是红色)。什么算法找到我的红点和形状边界之间的最近距离(图中的绿点)?
形状边框不是一系列线条,而是随机绘制的形状。
感谢。
答案 0 :(得分:4)
因此,您的形状被定义为位图,您可以访问像素。
您可以在点周围扫描不断增长的方块以获得边框像素。首先,检查像素本身。然后检查宽度为2的正方形,该正方形覆盖点的八个相邻像素。接下来,宽度4用于接下来的16个像素,依此类推。找到边框像素时,记录其距离并检查找到的最小距离。当广场宽度的一半大于当前最小距离时,您可以停止搜索。
另一种方法是在点周围绘制增长半径的Bresenham circles。该方法类似于方形方法,但您可以在击中时立即停止,因为所有点应该与您的点具有相同的距离。缺点是这种方法有些不准确,因为圆圈只是一个近似值。你也会错过沿着对角线的一些像素,因为布雷森汉姆的圆圈上都有人工制品。
(两种方法仍然非常暴力,在最坏的情况下,完全黑色的位图将访问每个节点。)
边框上的像素需要一个标准。您的形状是抗锯齿的,因此边框上的像素通过使其成为灰色阴影来平滑。如果您的标准是一个不是黑色的像素,您将在形状内选择一个点。如果你是纯白色的,你会在外面降落一点。也许最好选择灰度值大于0.5的像素作为边界。
如果必须找到相同形状的多个点的最近边界点,则可以预处理数据并使用[最近邻搜索]的其他方法。
答案 1 :(得分:2)
与往常一样,它取决于数据,在这种情况下,您的形状是什么样的以及有关您的起点的任何有用信息(它通常是靠近边界,是否经常靠近质心等等) )。
如果它们与您展示的相似,我可能会在开始时单独测试边界点。现在问题是如何找到边框而不必边缘检测整个形状。
问题是看起来你可以有一个尖锐的凹面边框(想象一个圆形的小穗状长条突入其中)。在这种情况下,您只需边缘检测形状并测试每个点。
我认为这些会奏效,但不要抱它。计算几何似乎很容易被理解,所以你可以在某个地方找到一个专业人士:
方法一 如果形状表现良好或者你不介意错误,试试这个:
1-绘制4条线(将形状划分为四个quandrants)。并检查每个边界的距离。我的意思是绘制是继续向北直到你击中一个白色像素,然后向南,向西和向东。
2-将目前已绘制的两条线与最近的交点分开,将它们创建的角度平分,然后将新线添加到集合中。
3-继续重复第二步,直到你有一个宽容你可以满意。
实际上你可以在此之前停下来,并且在足够小的间隔内,只需跟踪两个关闭点之间的边界,检查它们之间的每个点,以完善最终答案。
方法二(这将与表现不佳的形状一起使用并且在抗锯齿方面表现良好):
1-在任何方向画一条线,直到他撞到边界(黑到白)。这将是您的起始距离。
每次从黑色变为白色或从白色变为黑色时,在此距离处绘制一个圆圈。这些是你的交叉点。只要您有两个以上的点,将半径除以一半再试一次。
如果你没有分数,你的半径增加50%并再试一次(基本上二分搜索,直到你得到两分 - 如果你得到一分,你很幸运,找到你的答案)。
3-你的衣柜点位于你的两点之间的区域。沿边界运行检查每一个。
如果您愿意,为了降低第3步的成本,您可以继续执行第2步,直到您在步骤3中获得足够小的范围来蛮力。
同样为了防止非常不幸的开始,绘制四条初始线(也是东,南和西)并以最小距离开始。这些很容易绘制,大大降低了选择确切最长距离的可能性,并且意外地认为单个像素就是答案。
编辑:最后一次优化:由于对称性,您只需计算第一象限的圆点(构成圆的边界的点),然后镜像它们。应该大大减少计算时间。
答案 2 :(得分:1)
如果您根据' 定义距离,从开始像素到边距上的任何像素需要采取的最小步数'这个问题可以使用bread first search之类的最短路径搜索算法来解决,如果使用A* search algorithm则更好。