Algorithm 求直线交点的算法
我在某处看到了一个关于穿越线路的问题,并试图解决这个问题 有一个8位像素的64x64网格,上面有一组1像素宽的不同颜色的垂直和水平线。所有平行线之间至少有一个空间。问题在于找出每组彩色线的交叉线数量(例如,所有绿色交叉线都朝一个和计数)。并找出哪一组线路的交叉次数最少。此外,一种颜色的所有垂直线的大小都相同,而相同颜色的所有水平线的大小都相同 我有一些想法,但它们似乎都很低效。它需要遍历网格中的每个像素,如果遇到一种颜色,请确定它是垂直线还是水平线,然后一直沿着线的方向走,同时检查相邻的边是否有不同的颜色 我试图确定,首先计算每种颜色的水平线和垂直线的长度是否会加快这一过程。你们有什么好主意吗 这里有两个例子。请注意,平行线之间始终有一个空格Algorithm 求直线交点的算法,algorithm,line,Algorithm,Line,我在某处看到了一个关于穿越线路的问题,并试图解决这个问题 有一个8位像素的64x64网格,上面有一组1像素宽的不同颜色的垂直和水平线。所有平行线之间至少有一个空间。问题在于找出每组彩色线的交叉线数量(例如,所有绿色交叉线都朝一个和计数)。并找出哪一组线路的交叉次数最少。此外,一种颜色的所有垂直线的大小都相同,而相同颜色的所有水平线的大小都相同 我有一些想法,但它们似乎都很低效。它需要遍历网格中的每个像素,如果遇到一种颜色,请确定它是垂直线还是水平线,然后一直沿着线的方向走,同时检查相邻的边是否有
扫描像素网格实际上是非常快速和高效的。这是计算机视觉系统做这类事情的标准。很多这样的扫描会产生FIR过滤版本的图像,强调所搜索的细节种类 主要的技术术语是“卷积”(参见)。我认为它是一种加权移动平均数,虽然权重可以是负数。维基百科上的动画显示卷积使用了一个相当无聊的脉冲(它可能是一个更有趣的形状),以及一个一维信号(如声音)而不是二维(图像)信号,但这是一个非常普遍的概念 人们很容易认为,可以通过避免提前计算过滤版本来提高效率,但通常的效果是,由于没有预先计算所有像素,因此最终会对每个像素进行多次计算。换句话说,将过滤后的图像视为基于查找表的优化,或者是一种 这一速度如此之快的一些特殊原因是
- 再想一想,我可能已经理解了这个要求。从黑色和颜色中生成黑白图像,对其进行过滤,然后从中查找所有交点,这可能更有意义。一旦你有了交叉点,然后参考原始的黑色和彩色图像,对它们进行分类,以便计数。每像素的过滤和求交仍然非常有效。每像素的分类效率不是很高,但只能在几个点进行分类
.*.
***
.*.
点是零(与像素无关)或负值(更喜欢黑色)。星号为正值(首选白色)。也就是说,在十字路口寻找三乘三的十字路口
然后扫描过滤后的结果,寻找比某个阈值更亮的灰度像素,这是与您的模式最匹配的像素。如果您真的只需要精确的交叉点,您可能只接受完美匹配的颜色,但您可能需要考虑T型连接等。您是否只需要输入64x64网格?如果是这样的话,那么您正在寻找具有64x64风格的产品,因为没有其他方法可以确保您找到了所有的产品线。所以我假设你说的是操作层面的优化,而不是渐进的。我似乎记得旧的“Graphics Gems”系列有很多这样的例子,重点是减少指令数量。我自己更擅长渐进式问题,但这里有一些小想法: 格线单元的属性是格线[i,j]是绿色交点,如果
(grid[i,j] == green)
&&
(grid[i+1,j]==green || grid[i-1,j]==green)
&&
(grid[i,j+1]==green || grid[i, j-1]==green)
因此,您可以只扫描阵列一次,而不用担心显式检测水平线和垂直线。。。只要用这个关系来处理它,当你找到交叉点的时候,把它们算出来。所以,至少您只使用一个64x64循环,逻辑相当简单
因为没有两条平行线是直接相邻的,所以当你经过一个填充的单元格时,你知道你可以将你的内环计数器增加2。那会帮你省下一点工作
根据您的体系结构,您可能有一种快速的方法,可以使用自身的偏移副本创建整个栅格,这是计算上述交点公式的一种很酷的方法。但是,您仍然需要迭代整个过程,以找到剩余的填充单元(即交点)
即使你没有像图形处理器这样的东西可以让你和整个网格,如果颜色的数量少于你单词大小的一半,你也可以使用这个想法。例如,如果您有8种颜色和64位计算机,则可以将8个像素填充到单个无符号整数中。现在您可以一次对8个网格单元执行外循环比较操作。这可能是一个
1).a. 2).a.
bab bbb
.a. .a.
def straight_intersection(straight1, straight2):
p1x = straight1[0][0]
p1y = straight1[0][1]
p2x = straight1[1][0]
p2y = straight1[1][1]
p3x = straight2[0][0]
p3y = straight2[0][1]
p4x = straight2[1][0]
p4y = straight2[1][1]
x = p1y * p2x * p3x - p1y * p2x * p4x - p1x * p2y * p4x + p1x * p2y * p3x - p2x * p3x * p4y + p2x * p3y * p4x + p1x * p3x * p4y - p1x * p3y * p4x
x = x / (p2x * p3y - p2x * p4y - p1x * p3y + p1x * p4y + p4x * p2y - p4x * p1y - p3x * p2y + p3x * p1y)
y = ((p2y - p1y) * x + p1y * p2x - p1x * p2y) / (p2x - p1x)
return (x, y)