Basic 3d Cylinders

Looking to try and create some Cylinders, ideally I’d specify radius and height, then X,Y,Z location in space.
cyl

I played with using the streamtube example but wasn’t sure how to convert my desired radius and height to the streamtube input parameters.

I saw a similar post about using 3d mesh as well, but I’m not sure which would be best suited for the job.

Thanks!

@crator You can define each cylinder as a parameterized Surface. Here is a demo code:

import numpy as np
import plotly.graph_objects as go

def cylinder(r, h, a =0, nt=100, nv =50):
    """
    parametrize the cylinder of radius r, height h, base point a
    """
    theta = np.linspace(0, 2*np.pi, nt)
    v = np.linspace(a, a+h, nv )
    theta, v = np.meshgrid(theta, v)
    x = r*np.cos(theta)
    y = r*np.sin(theta)
    z = v
    return x, y, z

def boundary_circle(r, h, nt=100):
    """
    r - boundary circle radius
    h - height above xOy-plane where the circle is included
    returns the circle parameterization
    """
    theta = np.linspace(0, 2*np.pi, nt)
    x= r*np.cos(theta)
    y = r*np.sin(theta)
    z = h*np.ones(theta.shape)
    return x, y, z
r1 = 2
a1 = 0
h1 = 5

r2 = 1.35
a2 = 1
h2 = 3

x1, y1, z1 = cylinder(r1, h1, a=a1)
x2, y2, z2 = cylinder(r2, h2, a=a2)

colorscale = [[0, 'blue'],
             [1, 'blue']]

cyl1 = go.Surface(x=x1, y=y1, z=z1,
                 colorscale = colorscale,
                 showscale=False,
                 opacity=0.5)
xb_low, yb_low, zb_low = boundary_circle(r1, h=a1)
xb_up, yb_up, zb_up = boundary_circle(r1, h=a1+h1)

bcircles1 =go.Scatter3d(x = xb_low.tolist()+[None]+xb_up.tolist(),
                        y = yb_low.tolist()+[None]+yb_up.tolist(),
                        z = zb_low.tolist()+[None]+zb_up.tolist(),
                        mode ='lines',
                        line = dict(color='blue', width=2),
                        opacity =0.55, showlegend=False)

cyl2 = go.Surface(x=x2, y=y2, z=z2,
                 colorscale = colorscale,
                 showscale=False,
                 opacity=0.7)

xb_low, yb_low, zb_low = boundary_circle(r2, h=a2)
xb_up, yb_up, zb_up = boundary_circle(r2, h=a2+h2)

bcircles2 =go.Scatter3d(x = xb_low.tolist()+[None]+xb_up.tolist(),
                        y = yb_low.tolist()+[None]+yb_up.tolist(),
                        z = zb_low.tolist()+[None]+zb_up.tolist(),
                        mode ='lines',
                        line = dict(color='blue', width=2),
                        opacity =0.75, showlegend=False)

layout = go.Layout(scene_xaxis_visible=False, scene_yaxis_visible=False, scene_zaxis_visible=False)
fig =  go.Figure(data=[cyl2, bcircles2, cyl1, bcircles1], layout=layout)

fig.update_layout(scene_camera_eye_z= 0.55)
fig.layout.scene.camera.projection.type = "orthographic" #commenting this line you get a fig with perspective proj

fig.show()

2 Likes

Many thanks, this is exactly the solution I was looking for. Cheers