输入数据格式:
obj_1 = [(x1, y1, z1, x2, y2, z2), (...),...]
obj_2 = [(x1, y1, z1, x2, y2, z2), (...),...]
etc.
任务是找到一种方法,根据创建函数的调用顺序在旧对象下创建新对象。在本例中,我们首先创建一个 obj_1,然后创建一个 obj_2,它将隐藏在 obj_1 之下。然后创建了 obj_3,因此该对象隐藏在第一个和第二个对象之下。
所需的输出数据 - 用于绘制绘图的所有线的坐标
也许我需要使用 shapely 库,但我不确定。
物体的形状可以是任何形状,因此仅基于圆形、三角形和直线来编写代码是不太正确的。
from itertools import chain
from matplotlib import pyplot as plt
from more_itertools import batched
from shapely import Point, LineString, Polygon, MultiPoint, MultiLineString
from shapely.plotting import plot_polygon, plot_line, plot_points
像 OP 给出的文件中那样声明对象:
obj_1 = [(0.3931383333340818, 1.1771275460626884, 0.0,
将数据解析为有形状的对象:
shapely_objects = []
for obj in chain(obj_3, obj_1, obj_2):
n = len(obj) / 3
if n == 0:
continue
elif n == 1:
geom = Point(obj[0])
else:
data = list(batched(obj, 3, strict=True))
geom = LineString(data)
if geom.is_ring:
geom = Polygon(data)
shapely_objects.append(geom)
实际处理:
def overlay(geometries: Iterable[BaseGeometry]):
"""
Overlay shapely geometries: cut away the part of shapes that are underneath others.
First features in input will be underneath, last feature will not be cut.
"""
result = []
s = set()
tree = STRtree(geometries)
for idx, current_feature in enumerate(geometries):
s.add(idx)
overlapping_features = tree.geometries.take(list(set(tree.query(current_feature)) - s))
cut = current_feature.difference(unary_union(overlapping_features))
result.append(cut)
return result
shapes_overlain = overlay(shapely_objects)
可视化:
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4), sharex=True, sharey=True)
for shape in shapely_objects:
if isinstance(shape, Polygon):
plot_polygon(shape, color="w", add_points=False, ax=ax1)
elif isinstance(shape, LineString):
plot_line(shape, color="w", add_points=False, ax=ax1)
else:
plot_points(shape, color="w", add_points=False, ax=ax1)
for shape in shapes_overlain:
if isinstance(shape, Polygon):
plot_polygon(shape, color="w", add_points=False, ax=ax2)
elif isinstance(shape, (MultiLineString, LineString)):
plot_line(shape, color="w", add_points=False, ax=ax2)
elif isinstance(shape, (Point, MultiPoint)):
plot_points(shape, color="w", add_points=False, ax=ax2)
else:
raise ValueError(f"shape: {shape}")
ax1.set(facecolor="#242c34", xticks=[], yticks=[])
ax2.set(facecolor="#242c34", xticks=[], yticks=[])
ax1.set_title("Normal")
ax2.set_title("Overlain")
plt.show()