在python中获取一条直线的所有点 [英] Get all points of a straight line in python

查看:111
本文介绍了在python中获取一条直线的所有点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

非常简单,给定一个点A(x,y)和另一个点B(m,n),我需要一个函数,该函数可以在任何可迭代对象中返回它们之间所有点的列表[k,z]。 / p>

我只对整数感兴趣,因此不需要浮点数。



我需要最好的pythonic方法,因为此小功能将大量运行,并且是大型系统的关键支柱。



编辑:



@roippi,感谢指出有关整数的陷阱。从下面的代码中,您可以看到我尝试跨过x轴并获取对应的y,然后对y进行相同的操作。我的点集不会有任何非离散的坐标点,因此目前我可以忽略这个小缺陷

  import itertools 
#Vars
origin = {'x':0,'y':0}

deflope(原点,目标):
如果target ['x'] == origin ['x']:
返回0
else:
m =(target ['y']-origin ['y'])/(target ['x']-origin ['x'])
return m

def line_eqn(origin,target):
x = origin ['x']
y = origin ['y']
c =-(斜率(原点,目标)* x-y)
c = y-(斜率(原点,目标)* x)
#返回'y ='+ str(斜率(目标))+'x +'+ str(c)
m =斜率(原点,目标)
return {'m':m,'c':c}

def get_y(x,斜率,c):
#y = mx + c
y =(斜率* x)+ c
返回y

def get_x(y,坡度,c):
#x =(yc)/ m
如果坡度== 0:
c = 0#垂直线永不与y轴相交
如果为sl ope == 0:
斜率= 1#不除以零
x =(y-c)/斜率
返回x

def get_points(原点,目标):
coord_list = []
#在范围(i [origin ['x'],target ['x'] + 1)中,i沿x轴
步进:
eqn = line_eqn(来源,目标)
y = get_y(i,eqn ['m'],eqn ['c'])
coord_list.append([i,y])

#沿y轴
进行i在范围内(origin ['y'],target ['y'] + 1):
eqn = line_eqn(origin,target)
x = get_x(i,eqn ['m'],eqn ['c'])
coord_list.append([x,i])

#返回唯一列表
返回列表(itertools.groupby(sorted(coord_list))中的k,_的k)

origin = {'x':1,'y':3}
target = {' x':1,'y':6}

打印get_points(来源,目标)


解决方案

  def get_line(x1,y1,x2,y2):
分= []
issteep = abs(y2-y1)> abs(x2-x1)
如果是陡峭的:
x1,y1 = y1,x1
x2,y2 = y2,x2
rev =假
如果x1> x2:
x1,x2 = x2,x1
y1,y2 = y2,y1
rev =真
deltax = x2-x1
deltay = abs(y2- y1)
错误= int(deltax / 2)
y = y1
ystep = None
如果y1< y2:
ystep = 1
否则:
ystep = -1
对于x范围(x1,x2 + 1):
如果issteep:
points.append((y,x))
else:
points.append((x,y))
error-=如果错误<则保留
0:
y + = ystep
错误+ = deltax
#如果坐标反转则反转列表
如果rev:
points.reverse()
返回点


Very simply, given a point A(x,y) and another point B(m,n), I need a function that can return in any iterable object a list[k,z] of all points in between.

Am only interested in integer points, so no need for floats.

I need the best possible pythonic way because this 'little' function is going to be heavily run and is the key pillar of a larger system.

EDIT:

@roippi, thanks pointing out the gotcha concerning the integers. From my code below, you can see I try to step across the x axis and get corresponding y, then do the same for y. My set of points will not have any non-discrete co-ordinate point, so for the moment I can afford to overlook that small flaw

import itertools
#Vars
origin = {'x':0, 'y':0}

def slope(origin, target):
    if target['x'] == origin['x']:
        return 0
    else:
        m = (target['y'] - origin['y']) / (target['x'] - origin['x'])
        return m

def line_eqn(origin, target):
    x = origin['x']
    y = origin['y']
    c = -(slope(origin, target)*x - y)
    c = y - (slope(origin, target)*x)
    #return 'y = ' + str(slope(target)) + 'x + ' + str(c)
    m = slope(origin, target)
    return {'m':m, 'c':c}

def get_y(x, slope, c):
    # y = mx + c    
    y = (slope*x) + c
    return y

def get_x(y, slope, c):     
    #x = (y-c)/m
    if slope == 0:
        c = 0   #vertical lines never intersect with y-axis
    if slope == 0:
        slope = 1   #Do NOT divide by zero
    x = (y - c)/slope
    return x

def get_points(origin, target):
    coord_list = []
    #Step along x-axis
    for i in range(origin['x'], target['x']+1):     
        eqn = line_eqn(origin, target)
        y = get_y(i, eqn['m'], eqn['c'])        
        coord_list.append([i, y])

    #Step along y-axis
    for i in range(origin['y'], target['y']+1):
        eqn = line_eqn(origin, target)
        x = get_x(i, eqn['m'], eqn['c'])
        coord_list.append([x, i])

    #return unique list     
    return list(k for k,_ in itertools.groupby(sorted(coord_list)))

origin = {'x':1, 'y':3}
target = {'x':1, 'y':6}

print get_points(origin, target)

解决方案

def get_line(x1, y1, x2, y2):
    points = []
    issteep = abs(y2-y1) > abs(x2-x1)
    if issteep:
        x1, y1 = y1, x1
        x2, y2 = y2, x2
    rev = False
    if x1 > x2:
        x1, x2 = x2, x1
        y1, y2 = y2, y1
        rev = True
    deltax = x2 - x1
    deltay = abs(y2-y1)
    error = int(deltax / 2)
    y = y1
    ystep = None
    if y1 < y2:
        ystep = 1
    else:
        ystep = -1
    for x in range(x1, x2 + 1):
        if issteep:
            points.append((y, x))
        else:
            points.append((x, y))
        error -= deltay
        if error < 0:
            y += ystep
            error += deltax
    # Reverse the list if the coordinates were reversed
    if rev:
        points.reverse()
    return points

这篇关于在python中获取一条直线的所有点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆