如何同时按从上到下、从左到右排序点?Kotlin实现疑问
解决方案:按行分组后排序矩形
要实现 a → c → e → b → d 的排序效果,核心是先按行分组(同一水平行的矩形归为一组),再对组内按X升序、组间按行的垂直顺序排序,而不是简单的先X后Y全局排序。
问题分析
你尝试的「先X升序再Y升序」会把所有矩形按X轴横向排列,忽略了行的划分。而预期顺序是:先排上方行的矩形(a、c、e),左到右;再排下方行的矩形(b、d),左到右。这需要先按垂直方向(Y轴)分组,再组内横向排序。
实现步骤(Kotlin)
- 定义矩形数据类:存储标识和右下角坐标
- 按行分组:通过右下角Y值+容错阈值,将同一行的矩形归为一组
- 排序行组:按行的垂直位置从上到下排序(对应图像坐标系Y轴向下的情况,Y值越小越靠上)
- 组内排序:每行内按X升序排列,最后拼接所有组
代码示例
// 定义矩形数据结构 data class Rect(val id: String, val rightX: Int, val bottomY: Int) fun sortRectangles(rects: List<Rect>): List<Rect> { // 行分组容错阈值:根据实际矩形大小调整,确保同一行的Y值差异在阈值内 val rowThreshold = 10 // 按Y值分组:将Y值按阈值取整,实现同行业务分组 val rowGroups = rects.groupBy { rect -> rect.bottomY / rowThreshold } // 对行组按垂直顺序排序(Y轴向下时,Y值越小的行越靠上,排前面) val sortedRows = rowGroups.toSortedMap(compareBy { it }) // 每行内按X升序排序,拼接所有行的结果 return sortedRows.values.flatMap { row -> row.sortedBy { it.rightX } } } // 测试示例 fun main() { // 模拟你的矩形数据(对应预期顺序的坐标) val rects = listOf( Rect("b", 150, 200), Rect("a", 50, 100), Rect("d", 250, 200), Rect("c", 100, 100), Rect("e", 200, 100) ) val sortedResult = sortRectangles(rects) sortedResult.forEach { println(it.id) } // 输出结果:a → c → e → b → d }
注意事项
- 如果你的坐标系是数学坐标系(Y轴向上),行组排序需要改为降序:
toSortedMap(compareByDescending { it }) rowThreshold需要根据实际场景调整,比如矩形高度为50,阈值可设为20,避免因微小偏移导致分组错误- 若矩形对齐精度极高,也可直接用
bottomY作为分组键,无需阈值
内容的提问来源于stack exchange,提问作者Marian Pavel
相关产品推荐
相关产品推荐

