Python:从一条二维线中减去另一条线

问题描述 投票:0回答:1

问题

我需要计算两条线之间的差异(即从另一条线中减去一条线),这应该会产生一条输出线。

输入线和输出线可能包括垂直部分。 IE。线的 X 值可能不是单调递增的(尽管它们不会自行返回)。

这可能是最容易用示例来演示的:

输入

# lines represented as arrays of (X,Y) coordinates
line1 = [ (0,2), (4,2), (5,10), (15,10), (16,0), (20,0) ]
line2 = [ (0,2), (5,2), (10,5), (15,5), (15,0), (20,0) ]

这由以下图表表示(用 Excel 制作):

Line1 and Line2

输出

理想情况下,我正在寻找一个可以将

line1
line2
作为输入的库,并输出代表线之间差异的顶点(又名
line1
减去
line2
)。所以对于这个例子:

[ (0,0), (4,0), (5,8), (10,5), (15,5), (15,10), (16,0), (20,0) ]

再次,用图表可能更容易可视化 - 但请注意,我正在寻找一个将结果输出为 Python 对象的库 - 理想情况下是顶点或类似的 - 而不是一个只绘制图表的库

enter image description here

有关输入和输出数据的注释

  • 两点之间的直线是直线,而不是曲线
  • line1
    line2
    不包含所有相同的 X 值
  • 线上的 X 点永远不会向后但是我们可以在一条线上有多个具有相同 X 值的点,这些点彼此相邻 - 代表一条垂直线。例如。
    line2
    在 X=15 处包含重复点,因为从
    (X=15,Y=5)
    (X=15,Y=0)
    有一条垂直线。
  • 同样,输出数据可能需要表示垂直线。

我研究过的潜在解决方案

我对Python生态系统相对较新,并且不是数学/几何/图形专家。我尝试过研究各种 Python 库,但这些库的文档通常大量使用数学术语,因此我完全有可能遗漏了一些明显的东西。

Pandas Series - 看起来这会完美地工作if我有单调递增的X值...但我不...

SymPy Geometry - 它may可以用SymPy以我想要的方式减去2d线/多边形,但我无法在文档中找到任何明显的东西...

SciPy - 这个 StackOverflow 答案 使用

scipy.interpolate.interp1d
几乎我想做的事...

据我所知,您可以提供

interp1d
一系列点包括重复的X值,它将正确地表示线条的形状:

>>> x_values = [0,1,1]
>>> y_values = [0,0,10]
>>> curve = sc.interpolate.interp1d(x_values, y_values)
>>> curve(0)
array(0.)
>>> curve(1)
array(10.)
>>> curve(0.9999)
array(0.)

X=1 处有一条垂直线,因此获取 X 处的 Y 值<1 gives 0, while X=1 gives 10.

但是,如果我要做类似上面链接的 Stack Overflow 答案的事情:

# This would lose the duplicates representing the vertical line
all_x_values = sorted(set(line1_x_values + line2_x_values))

# Even if we had maintained all the X values, in our original example we would
# have two X=15 values here... The first call to line1(15) would need to return
# Y = 5, the second call to line1(15) would need to return Y = 0...
new_line_y_values = [line1(x) - line2(x) for x in all_x_values]

# And if we got this far with everything working, how do we extract the vertices
# from the new line - including multiple points at the same X-value for any vertical
# lines?
new_line = scipy.interpolate.interp1d(all_x_values, new_line_y_values)
python python-3.x math plot geometry
1个回答
0
投票

AFAIK,库中没有预建函数,但你可以做纯Python:

line3 = [
    (i, t1[1]-t2[1])
    for i in set(x for x,y in [xy for xy in [*line1, *line2]])
    for t1 in [(x,y) for x,y in line1 if x==i] or [(0, i)]
    for t2 in [(x,y) for x,y in line2 if x==i] or [(0, t1[1])]
]

输出:

line3 # [(0, 0), (4, 0), (5, 8), (10, 5), (15, 5), (15, 10), (16, 0), (20, 0)]

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.