import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
# 随机生成建筑块数据
def generate_building_blocks(num_blocks, grid_size=100, height_range=(5, 50), base_size_range=(10, 30)):
buildings = []
for _ in range(num_blocks):
# 随机选择建筑的底面起点
x = np.random.uniform(0, grid_size)
y = np.random.uniform(0, grid_size)
# 随机生成建筑的高度和底面大小
dx = np.random.uniform(*base_size_range)
dy = np.random.uniform(*base_size_range)
dz = np.random.uniform(*height_range)
buildings.append([x, y, dx, dy, dz])
return buildings
# 绘制建筑块
def plot_buildings(buildings, color='skyblue'):
fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(111, projection='3d')
for building in buildings:
x, y, dx, dy, dz = building
# 每个建筑的顶点坐标
# vertices = [
# [(x, y, 0), (x + dx, y, 0), (x + dx, y + dy, 0), (x, y + dy, 0)], # 底面
# [(x, y, dz), (x + dx, y, dz), (x + dx, y + dy, dz), (x, y + dy, dz)], # 顶面
# ]
vertices = [
[(x, y, 0), (x + dx, y, 0), (x + dx, y + dy, 0), (x, y + dy, 0)], # 底面
[(x, y, dz), (x + dx, y, dz), (x + dx, y + dy, dz), (x, y + dy, dz)], # 顶面
[(x, y, 0), (x + dx, y, 0), (x + dx, y, dz), (x, y, dz)], # 侧面1
[(x + dx, y, 0), (x + dx, y + dy, 0), (x + dx, y + dy, dz), (x + dx, y, dz)], # 侧面2
[(x, y + dy, 0), (x + dx, y + dy, 0), (x + dx, y + dy, dz), (x, y + dy, dz)], # 侧面3
[(x, y, 0), (x, y + dy, 0), (x, y + dy, dz), (x, y, dz)] # 侧面4
]
# 构建面
for v in vertices:
ax.add_collection3d(Poly3DCollection([v], color=color, alpha=0.7))
# 绘制立方体的竖直边
for i in range(4):
ax.plot([vertices[0][i][0], vertices[1][i][0]],
[vertices[0][i][1], vertices[1][i][1]],
[vertices[0][i][2], vertices[1][i][2]], color=color)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_box_aspect([1, 1, 0.5]) # 控制显示比例
plt.show()
# 生成随机建筑数据
buildings = generate_building_blocks(num_blocks=50, grid_size=200)
# 绘制随机建筑
plot_buildings(buildings)
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
# 随机生成建筑块数据
def generate_building_blocks(num_blocks, grid_size=100, height_range=(5, 50), base_size_range=(10, 30)):
buildings = []
for _ in range(num_blocks):
# 随机选择建筑的底面起点
x = np.random.uniform(0, grid_size)
y = np.random.uniform(0, grid_size)
# 随机生成建筑的高度和底面大小
dx = np.random.uniform(*base_size_range)
dy = np.random.uniform(*base_size_range)
dz = np.random.uniform(*height_range)
buildings.append([x, y, dx, dy, dz])
return buildings
# 绘制建筑块
# def plot_buildings(buildings, color='skyblue'):
def plot_buildings(buildings, color='skyblue', edge_color='gray', alpha=0.8):
fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(111, projection='3d')
ax.view_init(elev=50, azim=60) # 设置视角,elev 为俯仰角,azim 为方位角
for building in buildings:
x, y, dx, dy, dz = building
# 每个建筑的顶点坐标
# vertices = [
# [(x, y, 0), (x + dx, y, 0), (x + dx, y + dy, 0), (x, y + dy, 0)], # 底面
# [(x, y, dz), (x + dx, y, dz), (x + dx, y + dy, dz), (x, y + dy, dz)], # 顶面
# ]
vertices = [
[(x, y, 0), (x + dx, y, 0), (x + dx, y + dy, 0), (x, y + dy, 0)], # 底面
[(x, y, dz), (x + dx, y, dz), (x + dx, y + dy, dz), (x, y + dy, dz)], # 顶面
[(x, y, 0), (x + dx, y, 0), (x + dx, y, dz), (x, y, dz)], # 侧面1
[(x + dx, y, 0), (x + dx, y + dy, 0), (x + dx, y + dy, dz), (x + dx, y, dz)], # 侧面2
[(x, y + dy, 0), (x + dx, y + dy, 0), (x + dx, y + dy, dz), (x, y + dy, dz)], # 侧面3
[(x, y, 0), (x, y + dy, 0), (x, y + dy, dz), (x, y, dz)] # 侧面4
]
# 构建面
# for v in vertices:
# ax.add_collection3d(Poly3DCollection([v], color=color, alpha=0.7))
# 构建面,带有透明度和边框
for v in vertices:
poly = Poly3DCollection([v], facecolors=color, edgecolors=edge_color, linewidths=0.2, alpha=alpha)
ax.add_collection3d(poly)
# 绘制立方体的竖直边
for i in range(4):
ax.plot([vertices[0][i][0], vertices[1][i][0]],
[vertices[0][i][1], vertices[1][i][1]],
[vertices[0][i][2], vertices[1][i][2]], color=color)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_box_aspect([1, 1, 0.5]) # 控制显示比例
# 设置视角和比例
# ax.set_box_aspect([1, 1, 0.3])
# ax.set_axis_off() # 隐藏轴以增加美观
plt.show()
# 生成随机建筑数据
buildings = generate_building_blocks(num_blocks=50, grid_size=200)
# 绘制随机建筑
plot_buildings(buildings)