私は平行六面体を描いています。実際、私はpythonからキューブを描くスクリプトから始めました:
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
points = np.array([[-1, -1, -1],
[1, -1, -1 ],
[1, 1, -1],
[-1, 1, -1],
[-1, -1, 1],
[1, -1, 1 ],
[1, 1, 1],
[-1, 1, 1]])
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
r = [-1,1]
X, Y = np.meshgrid(r, r)
ax.plot_surface(X,Y,1, alpha=0.5)
ax.plot_surface(X,Y,-1, alpha=0.5)
ax.plot_surface(X,-1,Y, alpha=0.5)
ax.plot_surface(X,1,Y, alpha=0.5)
ax.plot_surface(1,X,Y, alpha=0.5)
ax.plot_surface(-1,X,Y, alpha=0.5)
ax.scatter3D(points[:, 0], points[:, 1], points[:, 2])
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()
平行六面体を得るために、ポイントマトリックスに次のマトリックスを乗算しました。
P =
[[2.06498904e-01 -6.30755443e-07 1.07477548e-03]
[1.61535574e-06 1.18897198e-01 7.85307721e-06]
[7.08353661e-02 4.48415767e-06 2.05395893e-01]]
として:
Z = np.zeros((8,3))
for i in range(8):
Z[i,:] = np.dot(points[i,:],P)
Z = 10.0*Z
私の考えは、次のように表現することです。
ax.scatter3D(Z[:, 0], Z[:, 1], Z[:, 2])
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()
そして、これは私が得るものです:
これらの異なるポイントにサーフェスを配置して、平行六面体を形成するにはどうすればよいですか(上記の立方体のように)?
3D PolyCollectionでサーフェスをプロット( example )
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection, Line3DCollection
import matplotlib.pyplot as plt
points = np.array([[-1, -1, -1],
[1, -1, -1 ],
[1, 1, -1],
[-1, 1, -1],
[-1, -1, 1],
[1, -1, 1 ],
[1, 1, 1],
[-1, 1, 1]])
P = [[2.06498904e-01 , -6.30755443e-07 , 1.07477548e-03],
[1.61535574e-06 , 1.18897198e-01 , 7.85307721e-06],
[7.08353661e-02 , 4.48415767e-06 , 2.05395893e-01]]
Z = np.zeros((8,3))
for i in range(8): Z[i,:] = np.dot(points[i,:],P)
Z = 10.0*Z
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
r = [-1,1]
X, Y = np.meshgrid(r, r)
# plot vertices
ax.scatter3D(Z[:, 0], Z[:, 1], Z[:, 2])
# list of sides' polygons of figure
verts = [[Z[0],Z[1],Z[2],Z[3]],
[Z[4],Z[5],Z[6],Z[7]],
[Z[0],Z[1],Z[5],Z[4]],
[Z[2],Z[3],Z[7],Z[6]],
[Z[1],Z[2],Z[6],Z[5]],
[Z[4],Z[7],Z[3],Z[0]]]
# plot sides
ax.add_collection3d(Poly3DCollection(verts,
facecolors='cyan', linewidths=1, edgecolors='r', alpha=.25))
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()
この質問のタイトルが「python draw 3D cube」であることを考えると、これはその質問をグーグルで検索したときに見つけた記事です。
私と同じように、単純に立方体を描きたい人のために、立方体の4つのポイント、最初にコーナー、次にそのコーナーに隣接する3つのポイントを取る次の関数を作成しました。
次に、キューブをプロットします。
機能は以下のとおりです。
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection, Line3DCollection
def plot_cube(cube_definition):
cube_definition_array = [
np.array(list(item))
for item in cube_definition
]
points = []
points += cube_definition_array
vectors = [
cube_definition_array[1] - cube_definition_array[0],
cube_definition_array[2] - cube_definition_array[0],
cube_definition_array[3] - cube_definition_array[0]
]
points += [cube_definition_array[0] + vectors[0] + vectors[1]]
points += [cube_definition_array[0] + vectors[0] + vectors[2]]
points += [cube_definition_array[0] + vectors[1] + vectors[2]]
points += [cube_definition_array[0] + vectors[0] + vectors[1] + vectors[2]]
points = np.array(points)
edges = [
[points[0], points[3], points[5], points[1]],
[points[1], points[5], points[7], points[4]],
[points[4], points[2], points[6], points[7]],
[points[2], points[6], points[3], points[0]],
[points[0], points[2], points[4], points[1]],
[points[3], points[6], points[7], points[5]]
]
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
faces = Poly3DCollection(edges, linewidths=1, edgecolors='k')
faces.set_facecolor((0,0,1,0.1))
ax.add_collection3d(faces)
# Plot the points themselves to force the scaling of the axes
ax.scatter(points[:,0], points[:,1], points[:,2], s=0)
ax.set_aspect('equal')
cube_definition = [
(0,0,0), (0,1,0), (1,0,0), (0,0,1)
]
plot_cube(cube_definition)
結果を与える:
より簡単なソリューションについては、他の回答( https://stackoverflow.com/a/49766400/3912576 )を参照してください。
Matplotlibのスケールを改善し、常に入力を強制的に立方体にする、より複雑な関数のセットを次に示します。
Cubify_cube_definitionに渡される最初のパラメーターは開始点、2番目のパラメーターは2番目の点、立方体の長さはこの点から定義され、3番目は回転点であり、1番目と2番目の長さに一致するように移動されます。
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection, Line3DCollection
def cubify_cube_definition(cube_definition):
cube_definition_array = [
np.array(list(item))
for item in cube_definition
]
start = cube_definition_array[0]
length_decider_vector = cube_definition_array[1] - cube_definition_array[0]
length = np.linalg.norm(length_decider_vector)
rotation_decider_vector = (cube_definition_array[2] - cube_definition_array[0])
rotation_decider_vector = rotation_decider_vector / np.linalg.norm(rotation_decider_vector) * length
orthogonal_vector = np.cross(length_decider_vector, rotation_decider_vector)
orthogonal_vector = orthogonal_vector / np.linalg.norm(orthogonal_vector) * length
orthogonal_length_decider_vector = np.cross(rotation_decider_vector, orthogonal_vector)
orthogonal_length_decider_vector = (
orthogonal_length_decider_vector / np.linalg.norm(orthogonal_length_decider_vector) * length)
final_points = [
Tuple(start),
Tuple(start + orthogonal_length_decider_vector),
Tuple(start + rotation_decider_vector),
Tuple(start + orthogonal_vector)
]
return final_points
def cube_vertices(cube_definition):
cube_definition_array = [
np.array(list(item))
for item in cube_definition
]
points = []
points += cube_definition_array
vectors = [
cube_definition_array[1] - cube_definition_array[0],
cube_definition_array[2] - cube_definition_array[0],
cube_definition_array[3] - cube_definition_array[0]
]
points += [cube_definition_array[0] + vectors[0] + vectors[1]]
points += [cube_definition_array[0] + vectors[0] + vectors[2]]
points += [cube_definition_array[0] + vectors[1] + vectors[2]]
points += [cube_definition_array[0] + vectors[0] + vectors[1] + vectors[2]]
points = np.array(points)
return points
def get_bounding_box(points):
x_min = np.min(points[:,0])
x_max = np.max(points[:,0])
y_min = np.min(points[:,1])
y_max = np.max(points[:,1])
z_min = np.min(points[:,2])
z_max = np.max(points[:,2])
max_range = np.array(
[x_max-x_min, y_max-y_min, z_max-z_min]).max() / 2.0
mid_x = (x_max+x_min) * 0.5
mid_y = (y_max+y_min) * 0.5
mid_z = (z_max+z_min) * 0.5
return [
[mid_x - max_range, mid_x + max_range],
[mid_y - max_range, mid_y + max_range],
[mid_z - max_range, mid_z + max_range]
]
def plot_cube(cube_definition):
points = cube_vertices(cube_definition)
edges = [
[points[0], points[3], points[5], points[1]],
[points[1], points[5], points[7], points[4]],
[points[4], points[2], points[6], points[7]],
[points[2], points[6], points[3], points[0]],
[points[0], points[2], points[4], points[1]],
[points[3], points[6], points[7], points[5]]
]
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
faces = Poly3DCollection(edges, linewidths=1, edgecolors='k')
faces.set_facecolor((0,0,1,0.1))
ax.add_collection3d(faces)
bounding_box = get_bounding_box(points)
ax.set_xlim(bounding_box[0])
ax.set_ylim(bounding_box[1])
ax.set_zlim(bounding_box[2])
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
ax.set_aspect('equal')
cube_definition = cubify_cube_definition([(0,0,0), (0,3,0), (1,1,0.3)])
plot_cube(cube_definition)
次の結果が生成されます。
Matplotlibと座標ジオメトリを使用して完了
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
def cube_coordinates(Edge_len,step_size):
X = np.arange(0,Edge_len+step_size,step_size)
Y = np.arange(0,Edge_len+step_size,step_size)
Z = np.arange(0,Edge_len+step_size,step_size)
temp=list()
for i in range(len(X)):
temp.append((X[i],0,0))
temp.append((0,Y[i],0))
temp.append((0,0,Z[i]))
temp.append((X[i],Edge_len,0))
temp.append((Edge_len,Y[i],0))
temp.append((0,Edge_len,Z[i]))
temp.append((X[i],Edge_len,Edge_len))
temp.append((Edge_len,Y[i],Edge_len))
temp.append((Edge_len,Edge_len,Z[i]))
temp.append((Edge_len,0,Z[i]))
temp.append((X[i],0,Edge_len))
temp.append((0,Y[i],Edge_len))
return temp
Edge_len = 10
A=cube_coordinates(Edge_len,0.01)
A=list(set(A))
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
A=Zip(*A)
X,Y,Z=list(A[0]),list(A[1]),list(A[2])
ax.scatter(X,Y,Z,c='g')
plt.show()