在这种简单的情况下,您可以执行以下三个步骤:找到形状的质心,根据 x 轴与当前点和质心形成的线之间的角度对兴趣点进行排序,遍历排序的点.
在这种情况下,质心的 x 坐标是每个兴趣点的 x 坐标之和除以兴趣点的总数(分别为质心的 y 坐标)。要计算角度,只需使用几乎任何语言的 atan2 即可。您的兴趣点是显示为 1 或 5 的那些,否则它不是角落(根据您的输入)。
不要误以为 Hough 会解决您的问题,即它不会给出您所追求的排序坐标。这也是一种昂贵的方法。此外,给定您的矩阵,您已经拥有其他方法无法比拟的完美信息(当然,问题是重复您提出的如此好的结果——在这些情况下,霍夫可能会证明是有用的)。
我的 Ruby 非常糟糕,因此请使用以下代码作为解决问题的指南:
include Math
data = ["0000000000000000",
"0000053335000000",
"0000030003000000",
"0000030003000000",
"0000020002000000",
"0533210001233500",
"0300000000000300",
"0300000000000300",
"0300000000000300",
"0533210001233500",
"0000020002000000",
"0000030003000000",
"0000030003000000",
"0000053335000000",
"0000000000000000",
"0000000000000000"]
corner_x = []
corner_y = []
data.each_with_index{|line, i|
line.split(//).each_with_index{|col, j|
if col == "1" || col == "5"
# Cartesian coords.
corner_x.push(j + 1)
corner_y.push(data.length - i)
end
}
}
centroid_y = corner_y.reduce(:+)/corner_y.length.to_f
centroid_x = corner_x.reduce(:+)/corner_x.length.to_f
corner = []
corner_x.zip(corner_y).each{|c|
dy = c[1] - centroid_y
dx = c[0] - centroid_x
theta = Math.atan2(dy, dx)
corner.push([theta, c])
}
corner.sort!
corner.each_cons(2) {|c|
puts "%s->%s" % [c[0][1].inspect, c[1][1].inspect]
}
这导致:
[2, 7]->[6, 7]
[6, 7]->[6, 3]
[6, 3]->[10, 3]
[10, 3]->[10, 7]
[10, 7]->[14, 7]
[14, 7]->[14, 11]
[14, 11]->[10, 11]
[10, 11]->[10, 15]
[10, 15]->[6, 15]
[6, 15]->[6, 11]
[6, 11]->[2, 11]
哪些是从最左下角开始的逆时针顺序的顶点(在笛卡尔坐标中,从最左下角的 (1, 1) 开始)。