[英]Shapely: intersection point between line and polygon in 3D
Last time I used shapely, I really had this nice import-and-fly-feeling . 上次我使用的时候,我真的有这种漂亮的导入和飞行感觉 。 However recently, I run into a rather non-intuitive behavior in this module, as I tried to find the intersection between a line segment and a triangle in 3D space. 然而,最近,我在这个模块中遇到了一个非常不直观的行为,因为我试图在3D空间中找到线段和三角形之间的交集。 Let's define a segment and a triangle as follow: 让我们定义一个段和一个三角形如下:
l = LineString([[1,0.5,0.5],[3,0.5,0.5]])
p = Polygon([[1.2,0.0,0.],[2.2,1.0,0.],[2.8,0.5,1.]])
To get their point of intersection I used l.intersection(p)
, and expected a point, namely POINT Z (POINT Z (2 0.5 0.25))
. 为了获得它们的交点,我使用了l.intersection(p)
,并期望一个点,即POINT Z (POINT Z (2 0.5 0.25))
。 It is illustrated with the blue dot below: 下面用蓝点说明:
Instead what I got was LINESTRING Z (1.7 0.5 0.25, 2.8 0.5 1)
- red line below - and frankly I am quite perplexed about what it is supposed to represent. 相反,我得到的是LINESTRING Z (1.7 0.5 0.25, 2.8 0.5 1)
- 下面的红线 - 坦率地说,我对它应该代表什么感到非常困惑。
Oddly enough, when the polygon/triangle is in the xz-plane and orthogonal to the line segment, the function behaves as one would expect. 奇怪的是,当多边形/三角形位于xz平面并与线段正交时,该函数的行为与预期的一样。 When the triangle is "leaning", however, it returns a line. 然而,当三角形“倾斜”时,它返回一条线。 This has temporarily lead me to believe that it returned the intersection between the line and the triangle's bounding box. 这暂时让我相信它返回了线和三角形边界框之间的交集。 The above red line proves otherwise. 以上红线证明不是这样。
So a workaround for this problem has been to read this very enlightening web-page , and adapt their C++
code to work with shapely objects. 因此,解决这个问题的方法是阅读这个非常有启发性的网页 ,并调整他们的C++
代码以使用形状对象。 The intersection
method works great to check whether the line goes through the polygon, and the function below finds the point of interest. intersection
方法非常适用于检查线是否穿过多边形,并且下面的函数找到了感兴趣的点。
def intersect3D_SegmentPlane(Segment, Plane):
# Points in Segment: Pn Points in Plane: Qn
P0, P1 = np.array(Segment.coords)
Q0, Q1, Q2 = np.array(Plane.exterior)[:-1]
# vectors in Plane
q1 = Q1 - Q0
q2 = Q2 - Q0
# vector normal to Plane
n = np.cross(q1, q2)/np.linalg.norm(np.cross(q1, q2))
u = P1 - P0 # Segment's direction vector
w = P0 - Q0 # vector from plane ref point to segment ref point
## Tests parallelism
if np.dot(n, u) == 0:
print "Segment and plane are parallel"
print "Either Segment is entirely in Plane or they never intersect."
return None
## if intersection is a point
else:
## Si is the scalar where P(Si) = P0 + Si*u lies in Plane
Si = np.dot(-n, w) / np.dot(n, u)
PSi = P0 + Si * u
return PSi
Not very import-and-fly anymore... 不再是进口和飞行......
So finally to my questions: 最后我的问题:
What does intersection
return when applied to 3D-objects and why is it a line? 应用于3D对象时intersection
返回什么?为什么它是一条线?
Is there a function in shapely that does what I want? 是否有一个形状上的功能,做我想要的? or any optional argument, tweak or dark magic trick? 或任何可选的参数,调整或黑魔术?
Is there any other libraries out there that would do this job while fulfilling my dreams of simplicity and laziness? 有没有其他图书馆可以完成这项工作,同时实现我的简单和懒惰的梦想?
unfortunately, as the documentation states: 不幸的是,正如文件所述:
Coordinate sequences are immutable. 坐标序列是不可变的。 A third z coordinate value may be used when constructing instances, but has no effect on geometric analysis. 在构造实例时可以使用第三个z坐标值,但对几何分析没有影响。 All operations are performed in the xy plane. 所有操作都在xy平面中执行。
One can verify this with: 可以通过以下方式验证:
from shapely.geometry import LineString, Polygon
l = LineString([[1,0.5,0.5],[3,0.5,0.5]])
p = Polygon([[1.2,0.0,0.],[2.2,1.0,0.],[2.8,0.5,1.]])
print(l.intersection(p))
#LINESTRING Z (1.7 0.5 0.25, 2.8 0.5 1)
l = LineString([[1,0.5],[3,0.5]])
p = Polygon([[1.2,0.0],[2.2,1.0],[2.8,0.5]])
print(l.intersection(p))
#LINESTRING (1.7 0.5, 2.8 0.5)
or even: 甚至:
from shapely.geometry import LineString, Polygon
l = LineString([[1,0.5,0],[3,0.5,0]])
p = Polygon([[1.2,0.0,1],[2.2,1.0,1],[2.8,0.5,1]])
print(l.intersects(p))
#True (even though the objects are in different z-planes)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.