python中的3D截锥 [英] 3D truncated cone in python

查看:30
本文介绍了python中的3D截锥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用完全相同的方法绘制一个截锥

I want to plot a truncated cone by using exactly the same method used in Plotting a solid cylinder centered on a plane in Matplotlib; which plots a cylinder when two points on the center of each base and the radius are known. On the other hand, I want to plot a truncated cone when the coordinates of the two points on the center of its bases and the radius of each base are known. It seems that I just should change the second last line of the function in the following program which plots a cylinder, but I could not do this in all of my efforts.

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()

I think I should change the radius as a function of v=p1-p0 as mentioned in: http://mathworld.wolfram.com/ConicalFrustum.html to be able to do this. Please let me know if there is any way to do this.

解决方案

Instead of a constant radius, R, make it change from R0 to 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()

这篇关于python中的3D截锥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆