如何从左上角到右下角排列坐标?
Posted
技术标签:
【中文标题】如何从左上角到右下角排列坐标?【英文标题】:How to order coordinates from top left to bottom right? 【发布时间】:2018-12-29 04:44:54 【问题描述】:我有一个类对象 my_rectangle 的列表:
class my_rectangle:
def __init__(self,text,x_start,y_start,x_end,y_end):
self.text=text
self.x_start=x_start
self.y_start=y_start
self.x_end=x_end
self.y_end=y_end
self.x_centroid=(self.x_start+self.x_end)/2
self.y_centroid=(self.y_start+self.y_end)/2
使用给出质心坐标的类属性(x_centroid
和y_centroid
),我想排序这个列表,使用从左到右然后从上到下的顺序(普通英文阅读顺序)?
说我有:
A=my_rectangle('Hi,',1,3,2,4)
B=my_rectangle('Im',3,3,3,4)
C=my_rectangle('New',1,1,2,2)
my_list=[C,B,A]
我想订购它来获得:
my_sorted_list=[A,B,C]
这是文本的表示:
""" Hi, I'm
New
"""
【问题讨论】:
【参考方案1】:生成排序列表是内置函数sorted()
的专长。
可以通过提供key
函数来完成使用多个值的排序,该键函数将值作为元组返回。然后根据元组的字典顺序对结果列表进行排序。
#UNTESTED
my_sorted_list = sorted(my_list, key=lambda item: (item.x_centroid, item.y_centroid))
【讨论】:
嗨。但是这个顺序会从左上到右下吗?【参考方案2】:您可以通过定义__lt__
方法使自定义类可排序。这会处理默认排序中使用的<
运算符。
class Rectangle:
def __init__(self,text,x_start,y_start,x_end,y_end):
self.text=text
self.x_start=x_start
self.y_start=y_start
self.x_end=x_end
self.y_end=y_end
@property
def centroid(self):
return (self.x_start+self.x_end)/2, (self.y_start+self.y_end)/2
def __lt__(self, other):
"""Using "reading order" in a coordinate system where 0,0 is bottom left"""
try:
x0, y0 = self.centroid
x1, y1 = other.centroid
return (-y0, x0) < (-y1, x1)
except AttributeError:
return NotImplemented
def __repr__(self):
return 'Rectangle: ' + self.text
我将centroid
定义为一个属性,以便在初始化矩形后更改任何其他坐标时它会更新。
如果您使用问题中的数据,您将获得此输出。
>>> rectangles = [
... Rectangle('A',1,3,2,4),
... Rectangle('B',3,3,3,4),
... Rectangle('C',1,1,2,2),
... ]
>>> print(sorted(rectangles))
[Rectangle: A, Rectangle: B, Rectangle: C]
【讨论】:
感谢您的回答。实际上我正在寻找从左上到右下的顺序,就像在阅读一样。您的解决方案从左下角到右上角。 这取决于坐标系。在计算机图形学中,0,0 点通常位于左上角。所以如果你想要一个不同的坐标系,改变__lt__
方法是很简单的。您没有提及您使用的是哪个坐标系。
我已经更新了我的答案,这样您就可以在左下角 0,0 的坐标系中获得阅读顺序
效果很好。最后一个问题。假设 y 坐标有一个小的差异(epsilon),因此算法计算它们在不同的线上,而这种差异足以让我们认为这些点位于同一条线上。给定 Rectangle('D',3,1.01,4,2.01) ,版本当前输出 [A,B,D,C] 而它应该是 [A,B,C,D] 因为矩形 D 位于C,和相同的 y 坐标(除了可能的小差异 0.01)
在质心坐标上使用round()。以上是关于如何从左上角到右下角排列坐标?的主要内容,如果未能解决你的问题,请参考以下文章