我得到一个坐标为n点的列表,比方说:
points = [(1, 2), (2, 3), (3, 4)]
我需要检查它们是否都在同一行上。我还决定考虑3种情况,以避免在x1 == x2时被零除。 所以这是我在Python中的代码:
# 2 points always lie on a line
if n <= 2:
print("yes")
else:
# leave only unique points
points = list(set(points))
x1, y1 = points[0]
x2, y2 = points[1]
# if two points have the same x coordinate
# then they lie on a vertical line and
# all other points have to have the same x coordinate too
if x2 == x1:
for i in range(2, len(points)):
if points[i][0] != x1:
print("no")
break
else: print("yes")
# same with a horizontal line
elif y2 == y1:
for i in range(2, len(points)):
if points[i][1] != y1:
print("no")
break
else: print("yes")
else:
a = (y2-y1)/(x2-x1)
b = y2 - a * x2
for i in range(2, len(points)):
x, y = points[i]
if (y != a * x + b):
print("no")
break
else: print("yes")
似乎我在代码中的某个地方犯了一个错误,但我并不真正理解它是什么。
答案 0 :(得分:1)
使用向量的叉积消除了必须处理可能发生被零除的特殊情况的复杂性。如果由三个点定义的两个向量形成的向量的叉积等于零,则三个点是共线的:
import math
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __sub__(self, other):
return Vector(self.x - other.x, self.y - other.y)
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def cross(self, other):
return self.x * other.y - self.y * other.x
def are_collinear(three_points):
a, b, c = three_points
# better use math.isclose than == to check for floats
return math.isclose((b-a).cross(c-a), 0.0)
points = [Point(1, 2), Point(2, 3), Point(3, 4)]
print(are_collinear(points))
# True
points = [Point(1, 2), Point(3, 3), Point(3, 4)]
print(are_collinear(points))
# False
答案 1 :(得分:0)
从列表中的任意点(例如第一个点)开始,如果所有其他点都与该点具有相同的斜率,则它们位于同一条线上。
def sameLine(points):
x0,y0 = points[0]
points = [ (x,y) for x,y in points if x != x0 or y != y0 ] # Other points
slopes = [ (y-y0)/(x-x0) if x!=x0 else None for x,y in points ] # None for vertical Line
return all( s == slopes[0] for s in slopes)