我想通过使用完全相同的方法绘制截锥 Plotting a solid cylinder centered on a plane in Matplotlib;当每个基座的中心上的两个点和半径已知时,绘制圆柱体。另一方面,我想在其基部中心的两个点的坐标和每个基部的半径已知时绘制截锥。 似乎我应该在下面的程序中更改函数的倒数第二行,它绘制了一个圆柱体,但我不能在所有的努力中做到这一点。
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from scipy.linalg import norm
import pylab as pllt
fig = pllt.figure()
ax = fig.add_subplot(1,1,1, projection='3d')
#ax = pllt.subplot2grid((2,2), (0,0), rowspan=2, projection='3d')
#axis and radius
def cylinder(p0,p1,R,ccc):
#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, 1, 0])
if (v == not_v).all():
not_v = np.array([0, 1, 0])
#make vector perpendicular to v
n1 = np.cross(v, not_v)
#print n1,'\t',norm(n1)
#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, 80)
theta = np.linspace(0, 2 * np.pi, 80)
#use meshgrid to make 2d arrays
t, theta = np.meshgrid(t, theta)
#generate coordinates for surface
X, Y, Z = [p0[i] + v[i] * t + R * np.sin(theta) * n1[i] + R * np.cos(theta) * n2[i] for i in [0, 1, 2]]
ax.plot_surface(X, Y, Z,color=ccc,linewidth=0, antialiased=False)
A0 = np.array([1, 3, 2])
A1 = np.array([8, 5, 9])
ax.set_xlim(0,10)
ax.set_ylim(0,10)
ax.set_zlim(0,10)
cylinder(A0,A1,1,'blue')
pllt.show()
我认为我应该将半径更改为v = p1-p0的函数,如下所述: http://mathworld.wolfram.com/ConicalFrustum.html能够做到这一点。 如果有任何办法,请告诉我。
答案 0 :(得分:1)
而不是常量半径R
,将其从R0
更改为R1
:
R = np.linspace(R0, R1, n)
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from scipy.linalg import norm
import pylab as plt
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection='3d')
def truncated_cone(p0, p1, R0, R1, color):
"""
Based on https://stackoverflow.com/a/39823124/190597 (astrokeat)
"""
# 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, 1, 0])
if (v == not_v).all():
not_v = np.array([0, 1, 0])
# make vector perpendicular to v
n1 = np.cross(v, not_v)
# print n1,'\t',norm(n1)
# 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
n = 80
t = np.linspace(0, mag, n)
theta = np.linspace(0, 2 * np.pi, n)
# use meshgrid to make 2d arrays
t, theta = np.meshgrid(t, theta)
R = np.linspace(R0, R1, n)
# generate coordinates for surface
X, Y, Z = [p0[i] + v[i] * t + R *
np.sin(theta) * n1[i] + R * np.cos(theta) * n2[i] for i in [0, 1, 2]]
ax.plot_surface(X, Y, Z, color=color, linewidth=0, antialiased=False)
A0 = np.array([1, 3, 2])
A1 = np.array([8, 5, 9])
ax.set_xlim(0, 10)
ax.set_ylim(0, 10)
ax.set_zlim(0, 10)
truncated_cone(A0, A1, 1, 5, 'blue')
plt.show()