Python 在Matplotlib中以平面为中心打印实心圆柱体

Python 在Matplotlib中以平面为中心打印实心圆柱体,python,matplotlib,plot,3d,plane,Python,Matplotlib,Plot,3d,Plane,我将一个平面拟合到3d中的一组点上,最初使用np.meshgrid为其指定任意大小,但现在我尝试以该平面为中心绘制一个圆柱体,并以相同的方式定向(这样平面拟合会将圆柱体的高度减半),但具有指定的半径和高度。我能找到的matplotlib中绘制的圆柱体的唯一示例是中空的,通常在顶部和底部打开。我希望我画的那个是实心的,这样我就能清楚地看到它所包围的点 下面是一个随机生成的平面的最小工作示例。因为我使用的平面总是由一个点和一个法向量给出,所以圆柱体也应该基于这些东西(加上提供的半径和在平面上下延伸的

我将一个平面拟合到3d中的一组点上,最初使用np.meshgrid为其指定任意大小,但现在我尝试以该平面为中心绘制一个圆柱体,并以相同的方式定向(这样平面拟合会将圆柱体的高度减半),但具有指定的半径和高度。我能找到的matplotlib中绘制的圆柱体的唯一示例是中空的,通常在顶部和底部打开。我希望我画的那个是实心的,这样我就能清楚地看到它所包围的点

下面是一个随机生成的平面的最小工作示例。因为我使用的平面总是由一个点和一个法向量给出,所以圆柱体也应该基于这些东西(加上提供的半径和在平面上下延伸的高度)


我修改了一个问题的解决方案,删除了奇特的着色并添加了端盖。如果要显示封闭的点,可以使用
alpha=0.5
或类似工具使圆柱体半透明

圆柱体的方向由长度为mag的单位向量v定义,它可能是曲面的法线

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Sun Oct  2 18:33:10 2016

Modified from https://stackoverflow.com/questions/38076682/how-to-add-colors-to-each-individual-face-of-a-cylinder-using-matplotlib
to add "end caps" and to undo fancy coloring.

@author: astrokeat
"""

import numpy as np
from matplotlib import pyplot as plt
from scipy.linalg import norm

#axis and radius
p0 = np.array([1, 3, 2]) #point at one end
p1 = np.array([8, 5, 9]) #point at other end
R = 5

#vector in direction of axis
v = p1 - p0

#find magnitude of vector
mag = norm(v)

#unit vector in direction of axis
v = v / mag

#make some vector not in the same direction as v
not_v = np.array([1, 0, 0])
if (v == not_v).all():
    not_v = np.array([0, 1, 0])

#make vector perpendicular to v
n1 = np.cross(v, not_v)
#normalize n1
n1 /= norm(n1)

#make unit vector perpendicular to v and n1
n2 = np.cross(v, n1)

#surface ranges over t from 0 to length of axis and 0 to 2*pi
t = np.linspace(0, mag, 2)
theta = np.linspace(0, 2 * np.pi, 100)
rsample = np.linspace(0, R, 2)

#use meshgrid to make 2d arrays
t, theta2 = np.meshgrid(t, theta)

rsample,theta = np.meshgrid(rsample, theta)

#generate coordinates for surface
# "Tube"
X, Y, Z = [p0[i] + v[i] * t + R * np.sin(theta2) * n1[i] + R * np.cos(theta2) *       n2[i] for i in [0, 1, 2]]
# "Bottom"
X2, Y2, Z2 = [p0[i] + rsample[i] * np.sin(theta) * n1[i] + rsample[i] * np.cos(theta) * n2[i] for i in [0, 1, 2]]
# "Top"
X3, Y3, Z3 = [p0[i] + v[i]*mag + rsample[i] * np.sin(theta) * n1[i] + rsample[i] * np.cos(theta) * n2[i] for i in [0, 1, 2]]


ax=plt.subplot(111, projection='3d')
ax.plot_surface(X, Y, Z, color='blue')
ax.plot_surface(X2, Y2, Z2, color='blue')
ax.plot_surface(X3, Y3, Z3, color='blue')

plt.show()
结果是:


我修改了一个问题的解决方案,删除了奇特的阴影并添加了端盖。如果要显示封闭的点,可以使用
alpha=0.5
或类似工具使圆柱体半透明

圆柱体的方向由长度为mag的单位向量v定义,它可能是曲面的法线

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Sun Oct  2 18:33:10 2016

Modified from https://stackoverflow.com/questions/38076682/how-to-add-colors-to-each-individual-face-of-a-cylinder-using-matplotlib
to add "end caps" and to undo fancy coloring.

@author: astrokeat
"""

import numpy as np
from matplotlib import pyplot as plt
from scipy.linalg import norm

#axis and radius
p0 = np.array([1, 3, 2]) #point at one end
p1 = np.array([8, 5, 9]) #point at other end
R = 5

#vector in direction of axis
v = p1 - p0

#find magnitude of vector
mag = norm(v)

#unit vector in direction of axis
v = v / mag

#make some vector not in the same direction as v
not_v = np.array([1, 0, 0])
if (v == not_v).all():
    not_v = np.array([0, 1, 0])

#make vector perpendicular to v
n1 = np.cross(v, not_v)
#normalize n1
n1 /= norm(n1)

#make unit vector perpendicular to v and n1
n2 = np.cross(v, n1)

#surface ranges over t from 0 to length of axis and 0 to 2*pi
t = np.linspace(0, mag, 2)
theta = np.linspace(0, 2 * np.pi, 100)
rsample = np.linspace(0, R, 2)

#use meshgrid to make 2d arrays
t, theta2 = np.meshgrid(t, theta)

rsample,theta = np.meshgrid(rsample, theta)

#generate coordinates for surface
# "Tube"
X, Y, Z = [p0[i] + v[i] * t + R * np.sin(theta2) * n1[i] + R * np.cos(theta2) *       n2[i] for i in [0, 1, 2]]
# "Bottom"
X2, Y2, Z2 = [p0[i] + rsample[i] * np.sin(theta) * n1[i] + rsample[i] * np.cos(theta) * n2[i] for i in [0, 1, 2]]
# "Top"
X3, Y3, Z3 = [p0[i] + v[i]*mag + rsample[i] * np.sin(theta) * n1[i] + rsample[i] * np.cos(theta) * n2[i] for i in [0, 1, 2]]


ax=plt.subplot(111, projection='3d')
ax.plot_surface(X, Y, Z, color='blue')
ax.plot_surface(X2, Y2, Z2, color='blue')
ax.plot_surface(X3, Y3, Z3, color='blue')

plt.show()
结果是: