2015-08-31 2 views
0

Я хотел бы нарисовать цилиндр с использованием matplotlib вдоль длины точки (x1, y1) и (x2, y2) с заданным радиусом r. Пожалуйста, дайте мне знать, как это сделать.Как нарисовать цилиндр с использованием matplotlib вдоль длины точки (x1, y1) и (x2, y2) с заданным радиусом?

+1

цилиндр просто сложены круги ... Вы можете вычислить точки края окружности с 'х, у = center_x + соз (угол) * радиус, center_y + sin (angle) * radius' –

ответ

7

Просто для удовольствия я собираюсь обобщить это на любую ось (x0, y0, z0) на (x1, y1, z1). Установите z0 и z1 в 0, если вам нужна ось в плоскости xy.

Вы можете найти векторное уравнение для оси довольно легко, найдя единичный вектор в том же направлении, что и ось, затем добавив его к p0 и масштабируя по длине оси. Обычно вы можете найти координаты круга с x = x0 + cos (theta) * R и y = y0 + sin (theta) * R, но круги не находятся в плоскости xy, поэтому нам понадобится сделать наши собственные оси единичными векторами, перпендикулярными оси цилиндра и друг друга, а затем получить координаты xyz. Я использовал этот сайт, чтобы помочь мне разобраться в этом: http://mathforum.org/library/drmath/view/51734.html. Вот код:

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

fig = plt.figure() 
ax = fig.add_subplot(111, projection='3d') 
origin = np.array([0, 0, 0]) 
#axis and radius 
p0 = np.array([1, 3, 2]) 
p1 = np.array([8, 5, 9]) 
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, 100) 
theta = np.linspace(0, 2 * np.pi, 100) 
#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) 
#plot axis 
ax.plot(*zip(p0, p1), color = 'red') 
ax.set_xlim(0, 10) 
ax.set_ylim(0, 10) 
ax.set_zlim(0, 10) 
plt.show() 

figure of 3d cylinder surface

+0

Можно ли сделать этот цилиндр с двумя концами, имеющими два разных радиуса? – coolswastik

+0

Нет, потому что тогда это будет усеченный конус, а не цилиндр. Если вы хотите это сделать, вам нужно, чтобы R линейно изменялась как функция t, при R = R1, когда t = 0 и R = R2, когда t = длина оси. –

+0

Спасибо! Эми. Это решило мою проблему. :) – coolswastik

Смежные вопросы