python 自定义 三维空间中画立方体

发布时间 2023-08-23 15:57:51作者: 时光如你般美好

第一种方法

from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.pyplot import MultipleLocator


def cuboid_data2(o, size=(10, 10, 10)):
    X = [[[0, 1, 0], [0, 0, 0], [1, 0, 0], [1, 1, 0]],
         [[0, 0, 0], [0, 0, 1], [1, 0, 1], [1, 0, 0]],
         [[1, 0, 1], [1, 0, 0], [1, 1, 0], [1, 1, 1]],
         [[0, 0, 1], [0, 0, 0], [0, 1, 0], [0, 1, 1]],
         [[0, 1, 0], [0, 1, 1], [1, 1, 1], [1, 1, 0]],
         [[0, 1, 1], [0, 0, 1], [1, 0, 1], [1, 1, 1]]]
    X = np.array(X).astype(float)
    for i in range(3):
        X[:, :, i] *= size[i]
    X += np.array(o)
    return X


def plotCubeAt2(positions, sizes=None, colors=None, **kwargs):
    if not isinstance(colors, (list, np.ndarray)):
        colors = ["C0"] * len(positions)

    if not isinstance(sizes, (list, np.ndarray)):
        sizes = [(1, 1, 1)] * len(positions)
    g = []
    for p, s, c in zip(positions, sizes, colors):
       g.append(cuboid_data2(p, size=s))
    return Poly3DCollection(np.concatenate(g), facecolors=np.repeat(colors, 6), alpha=0.6, **kwargs)


positions = [(50, 50, 50), (10, 10, 10)]
sizes = [(20, 20, 20), (20, 20, 20)]
colors = ["Gray", "Gray"]

fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")
ax.set_aspect('equal')

pc = plotCubeAt2(positions, sizes, colors=colors, edgecolor="k")  # edgecolor边缘线要不要
ax.add_collection3d(pc)

ax.set_xlim([0, 100])
ax.set_ylim([0, 100])
ax.set_zlim([0, 100])


# 设置坐标轴刻度
major_locator = MultipleLocator(10)
ax.xaxis.set_major_locator(major_locator)
ax.yaxis.set_major_locator(major_locator)
ax.zaxis.set_major_locator(major_locator)

plt.show()

效果图

image

第二种方法

from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt

def cuboid_data(o, size=(1,1,1)):
    # code taken from
    # https://stackoverflow.com/a/35978146/4124317
    # suppose axis direction: x: to left; y: to inside; z: to upper
    # get the length, width, and height
    l, w, h = size
    x = [[o[0], o[0] + l, o[0] + l, o[0], o[0]],
         [o[0], o[0] + l, o[0] + l, o[0], o[0]],
         [o[0], o[0] + l, o[0] + l, o[0], o[0]],
         [o[0], o[0] + l, o[0] + l, o[0], o[0]]]
    y = [[o[1], o[1], o[1] + w, o[1] + w, o[1]],
         [o[1], o[1], o[1] + w, o[1] + w, o[1]],
         [o[1], o[1], o[1], o[1], o[1]],
         [o[1] + w, o[1] + w, o[1] + w, o[1] + w, o[1] + w]]
    z = [[o[2], o[2], o[2], o[2], o[2]],
         [o[2] + h, o[2] + h, o[2] + h, o[2] + h, o[2] + h],
         [o[2], o[2], o[2] + h, o[2] + h, o[2]],
         [o[2], o[2], o[2] + h, o[2] + h, o[2]]]
    return np.array(x), np.array(y), np.array(z)


def plotCubeAt(pos=(0,0,0), size=(1,1,1), ax=None,**kwargs):
    # Plotting a cube element at position pos
    if ax !=None:
        X, Y, Z = cuboid_data( pos, size )
        ax.plot_surface(X, Y, Z, rstride=1, cstride=1, **kwargs)


positions = [(-3,5,-2),(1,7,1)]
sizes = [(4,5,3), (3,3,7)]
colors = ["crimson","limegreen"]


fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")
ax.set_aspect('equal')

for p,s,c in zip(positions,sizes,colors):
    plotCubeAt(pos=p, size=s, ax=ax, color=c)

plt.show()

效果图

image

第三种方法


import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.pyplot import MultipleLocator

# 定义矩阵的长宽高
length = 10
width = 10
height = 10

# 创建三维数据矩阵
matrix = np.zeros((length, width, height))

# 定义障碍物大小和位置
obstacle_length = 2
obstacle_width = 2
obstacle_height = 3
obstacle_pos = (1, 1, 1)  # 障碍物位置,从0开始计数

# 在矩阵中标记障碍物
matrix[obstacle_pos[0]:obstacle_pos[0]+obstacle_length,
       obstacle_pos[1]:obstacle_pos[1]+obstacle_width,
       obstacle_pos[2]:obstacle_pos[2]+obstacle_height] = 1

# 绘制三维空间
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# 找出非零元素的索引
indexes = np.where(matrix != 0)

# 绘制障碍物
ax.scatter(indexes[0], indexes[1], indexes[2], c='red')

# 设置坐标轴标签
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')

# 设置坐标轴范围
ax.set_xlim([0, length-1])
ax.set_ylim([0, width-1])
ax.set_zlim([0, height-1])

# 设置坐标轴刻度
major_locator = MultipleLocator(1)
ax.xaxis.set_major_locator(major_locator)
ax.yaxis.set_major_locator(major_locator)
ax.zaxis.set_major_locator(major_locator)

# 显示图形
plt.show()

效果图

image

第四种方法

import numpy as np
import matplotlib.pyplot as plt
vertices = np.array([
    [0, 0, 0],
    [1, 0, 0],
    [1, 1, 0],
    [0, 1, 0],
    [0, 0, 1],
    [1, 0, 1],
    [1, 1, 1],
    [0, 1, 1]
])

edges = np.array([
    [0, 1],
    [1, 2],
    [2, 3],
    [3, 0],
    [4, 5],
    [5, 6],
    [6, 7],
    [7, 4],
    [0, 4],
    [1, 5],
    [2, 6],
    [3, 7]
])

fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")

for i, vertex in enumerate(vertices):
    ax.scatter(vertex[0], vertex[1], vertex[2], c="c", marker="o")

for i, edge in enumerate(edges):
    x1, y1, z1 = vertices[edge[0]]
    x2, y2, z2 = vertices[edge[1]]
    ax.plot([x1, x2], [y1, y2], [z1, z2], c="k")

ax.set_xlim([-1, 2])
ax.set_ylim([-1, 2])
ax.set_zlim([-1, 2])

plt.show()

效果图

image