合并相邻的平行线

本文关键字:平行线 合并 | 更新日期: 2023-09-27 18:17:03

有一个只有垂直线和水平线的图像。但是有一些线是相同的,或者它们彼此很接近,但它们应该组合成一条线。我也写了循环添加行在一个新的列表,速度很慢。所以我想知道有没有什么有效的方法可以把这些相邻的直线组合成一条直线。

代码如下:

for (int i = 0; i < RecoverLine_list.Count; i++) {
        for (int j = 0; j < RecoverLine_list.Count; j++) {
            for (int m = 0; m < RecoverLine_list.Count; m++) {
                if (RecoverLine_list[i] != RecoverLine_list[j] 
                 && RecoverLine_list[i] != RecoverLine_list[m] 
                 && RecoverLine_list[j] != RecoverLine_list[m]) {
                    if (RecoverLine_list[i].orientation == 0 
                     && RecoverLine_list[j].orientation == 0 
                     && RecoverLine_list[m].orientation == 0) {
                        if (Math.Abs(RecoverLine_list[i].P1.Y - RecoverLine_list[j].P1.Y) < 3 
                         && Math.Abs(RecoverLine_list[i].P1.Y - RecoverLine_list[m].P1.Y) < 3 
                         && Math.Abs(RecoverLine_list[j].P1.Y - RecoverLine_list[m].P1.Y) < 3) {
                            // define RecoverLine_list[i] as grid line
                            GridLine_list.Add(RecoverLine_list[i]);
                        }
                    }
                }
            }
        }
    }

合并相邻的平行线

(重写)所以,假设你想以某种方式过滤水平和垂直线,这是"相似",并希望代码和良好的条件,"相似"应该是什么,那么这里是我的想法:

第一行横线和竖线分割:

List<Line> vert = new List<Line>();
List<Line> horiz = new List<Line>();
foreach(Line ln in RecoverLine_list)
    if(ln.orientation == 0) horiz.Add(ln);
    else vert.Add(ln);
horiz.Sort(x, y => x.P1.Y.CompareTo(y.P1.Y));
vert.Sort(x, y => x.P1.X.CompareTo(y.P1.X));

或类似的东西(不确定你的方向是什么,我只是猜测,包括使用lambdas排序的编码)。

然后,您可以一次搜索行,提取好的行:

List<Line> filtered = new List<Line>();
for(int i = 0; i < horiz.Count; i++) {
    filtered.Add(ln); // always add, we can skip next:
    if(i+1 >= horiz.Count) break;
    if(Math.Abs(horiz[i].P1.Y - horiz[i+1].P1.Y) <= 3)
    && Math.Abs(horiz[i].P1.X - horiz[i+1].P1.X) <= 3)
    && Math.Abs(horiz[i].P2.X - horiz[i+1].P2.X) <= 3))
        i++; // skip this line for being similar
}

,但这不是最终解,因为我们可以在一个坐标中有彼此接近的线,但在另一个坐标中没有。所以我们需要添加内循环:

for(int i = 0; i < horiz.Count-1; i++) {
    for(int j = i+1; j < horiz.Count; j++) {
        if((horiz[j].P1.Y - horiz[i].P1.Y) > 3)
           break; // this one is too far, all next will be
        if(Math.Abs(horiz[i].P1.Y - horiz[j].P1.Y) <= 3)
        && Math.Abs(horiz[i].P1.X - horiz[j].P1.X) <= 3)
        && Math.Abs(horiz[i].P2.X - horiz[j].P2.X) <= 3))
            horiz.RemoveAt(j--); // skip this line for being similar
}}

明白了吗?垂直线也一样。