Все целые точки на отрезке
Я ищу короткий умный способ найти все целые точки на отрезке. 2 точки также являются целыми числами, и линия может быть под углом 0,45,90,135 и т. Д. Градусов.
Вот мой длинный код (до сих пор случаи 90 градусов):
def getPoints(p1,p2)
if p1[0] == p2[0]:
if p1[1] < p2[1]:
return [(p1[0],x) for x in range(p1[1],p2[1])]
else:
return [(p1[0],x) for x in range(p1[1],p2[1],-1)]
if p2[1] == p2[1]:
if p1[0] < p2[0]:
return [(x,p1[1]) for x in range(p1[0],p2[0])]
else:
return [(x,p1[1]) for x in range(p1[0],p2[0],-1)]
РЕДАКТИРОВАТЬ: Я не упомянул это достаточно ясно, но наклон всегда будет целым числом -1, 0 или 1, есть 8 случаев, которые необходимо проверить.
4 ответа
Уменьшите наклон до наименьших значений (p/q), затем переходите от одной конечной точки отрезка к другой с шагом p по вертикали и q по горизонтали. Один и тот же код может работать для вертикальных отрезков, если ваш код сокращения до минимальных сокращает 5/0 до 1/0.
я мог бы написать код, который работает, но количество повторяющегося кода отталкивает меня, поэтому я обратился к вам, ребята
Это может вынести много улучшений, но, возможно, это поможет вам в этом. (извините, сейчас нет времени, чтобы сделать это лучше!)
def points(p1,p2):
slope = (p2[1]-p1[1])/float(p2[0]-p1[0])
[(x,x*slope) for x in range (p1[0], p2[0]) if int(x*slope) == x*slope)]
Сделайте немного математики для каждой пары точек, вычислите m & c для mx+c и сравните его с формулами для рассматриваемых линий. (NB. Вы получите некоторое деление на нули, чтобы справиться.)
Расширение ответа @Jon Kiparsky.
def points_on_line(p1, p2):
fx, fy = p1
sx, sy = p2
if fx == sx and fy == sy:
return []
elif fx == sx:
return [(fx, y) for y in range(fy+1, sy)]
elif fy == sy:
return [(x, fy) for x in range(fx+1, sx)]
elif fx > sx and fy > sy:
p1, p2 = p2, p1
slope = (p2[1] - p1[1]) / float(p2[0] - p1[0])
return [(x, int(x*slope)) for x in range(p1[0], p2[0]) if int(x*slope) == x*slope and (x, int(x*slope)) != p1]
def getpoints(p1, p2):
# Sort both points first.
(x1, y1), (x2, y2) = sorted([p1, p2])
a = b = 0.0
# Not interesting case.
if x1 == x2:
yield p1
# First point is in (0, y).
if x1 == 0.0:
b = y1
a = (y2 - y1) / x2
elif x2 == 0.0:
# Second point is in (0, y).
b = y2
a = (y1 - y2) / x1
else:
# Both points are valid.
b = (y2 - (y1 * x2) / x1) / (1 - (x2 / x1))
a = (y1 - b) / x1
for x in xrange(int(x1), int(x2) + 1):
y = a * float(x) + b
# Delta could be increased for lower precision.
if abs(y - round(y)) == 0:
yield (x, y)