简体   繁体   中英

cylinder “cuts” a sphere in python

As i can't draw it well by hand, I am using python/matplotlib to draw a sphere and a cylinder than "cut through" and make a curve. The cylinder has equation

x^2+y^2-a*x=0

The sphere is done with the equation:

x^2+y^2+z^2=a^2

I input a and draw the sphere with

# -*- coding: utf-8 -*-
from numpy import*
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
fig=plt.figure()
ax=Axes3D(fig)
a=input('a? ')
u,v=mgrid[0:2*pi:20j,0:pi/2:10j]
x=a*cos(u)*sin(v)
y=a*sin(u)*sin(v)
z=a*cos(v)
ax.plot_wireframe(x,y,z,color='b')
ax.set_xlabel("x"); ax.set_ylabel("y"); ax.set_zlabel("z")
plt.show()
plt.close()

Now i want to draw the cylinder and if able, the curve that makes the intersection of the two figures... but no idea...

I think i forgot to say that is first section (all positive) of xyz coordenates

the equivalent parametric equations for the cylinder would be

x = b * sin(u) + xoff
y = b * cos(u) + yoff
z = v

assuming you want a different radius and origin.

I don't really understand what you are trying to get as output. Presumably not the intersection of two surfaces - which would be a curve (I would have thought a sphere wedge was a solid shape http://en.wikipedia.org/wiki/Spherical_wedge ) Could you do what you want with blender?

EDIT - offsets.

You can create the curve as array of points which you calculate along these lines http://en.wikipedia.org/wiki/Sphere%E2%80%93cylinder_intersection (are those pictures the kind of thing you want?)

EDIT2 - just looked at your code and noticed a couple of minor issues such as not making a full sphere. Anyway here's something to start with - you need to filter out the square roots of negative numbers where the object don't intersect!

...
u,v=mgrid[0:2*pi:50j,0:pi:25j]

a1 = input('a1? ')
x1 = a1 * cos(u) * sin(v)
y1 = a1 * sin(u) * sin(v)
z1 = a1 * cos(v)
ax.plot_wireframe(x1, y1, z1, color='b')

a2 = input('a2? ')
xoff = input('offset? ')
x2 = a2 * cos(u) + xoff
y2 = a2 * sin(u)
z2 = (v - pi/2) * a1 / (pi/2)
ax.plot_wireframe(x2, y2, z2, color='g')

x3 = a2 * cos(u[:,0]) + xoff
y3 = a2 * sin(u[:,0])
zsq = (a1**2 - x3**2 - y3**2)
mask = where(zsq > 0)
x3 = x3[mask]
y3 = y3[mask]
z3 = zsq[mask] ** 0.5
ax.plot(x3, y3, z3, color='r')
ax.plot(x3, y3, -z3, color='r')
...

在此处输入图片说明

It seems that you want to represent the nice Viviani's curve .

Using your spherical coordinates, the cyclinder equation becomes

a²sin²(v)-a²cos(u)sin(v),

or

sin(v)=cos(u),

or

u+v=π/2.

So it suffices to vary one of u or v , deduce the other parameter and plug into the spherical-to-Cartesian transform to get as many points as you want along the curve and draw using plot .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM