2

I'm trying to create a bottle as a revolution solid using MatplotLib. I've got this points: Image of the coordinates

Which in terms of coordinates are:

coords = [(0.00823433249299356, 0.06230346394288128),
 (0.04086905251958573, 0.0648935210878489),
 (0.08386400112604843, 0.0648935210878489),
 (0.11753474401062763, 0.06541153251684242),
 (0.14239929260231693, 0.05712334965294601),
 (0.19109236692770842, 0.05401528107898486),
 (0.2278711783862488, 0.05142522393401722),
 (0.24133947554008045, 0.04158300678314021)]

The polynomial (more or less accurate) is:

Lambda(x, -19493.7965633925*x**6 + 13024.3747084876*x**5 - 3228.16456296349*x**4 + 368.816080918066*x**3 - 20.500262217588*x**2 + 0.545840273670868*x + 0.0590464366057008)

Which I get by:

# Getting the polynomial:
z = np.polyfit(xdata, ydata, 6)
# Being xdata and ydata the 2 vector from the coordinates
x = sp.symbols('x', real=True) 
P = sp.Lambda(x,sum((a*x**i for i,a in enumerate(z[::-1]))))
print(P)

The point describe the outline of the bottle (cast your imagination) being the bottle in the plane XY. How can I get, from that curve, a solid of revolution that recreates a bottle?

My objective is to be able to rotate the generator curve and create a solid of revolution, what I've tried is:

# Create the polynomial
pol = sp.lambdify(x,P(x),"numpy")
# Create the matrix of points
X = np.linspace(xdata[0], xdata[-1], 50)
Y = pol(X)
X, Y = np.meshgrid(X, Y)

# As long as a bottle is no more than a big amount of small cylinders, my 
# equation should be more or less like:
# Z = x**2 + y** -R**2
# So we create here the equation
Z = X**2 + Y**2 - (Y - 0.0115)**2

# We create the #D figure
fig = plt.figure()
ax = plt.axes(projection="3d")
# And we representate it
surf = ax.plot_surface(X, Y, Z)  

# We change the labels
ax.set_xlabel('$x$')
ax.set_ylabel('$y$')
ax.set_zlabel('$z$')

# And show the figure
plt.show()

The problem is that what I get is no longer a bottle (and I think is because how I'm using the plot_surface (I don't get very well how to use it by reading the documentation).

What I got is: Image of the plotting. First I thought that was a problem related to the zoom, but I changed it and the figure is the same

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
DecowVR
  • 591
  • 4
  • 9

1 Answers1

2

I'll reference unutbu's answer to a similar question.

import numpy as np 
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d as axes3d

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection='3d')

# grab more points between your coordinates, say 100 points
u = np.linspace(0.00823433249299356, 0.24133947554008045, 100)

def polynomial(x):
    return -19493.7965633925*x**6 + 13024.3747084876*x**5 - 3228.16456296349*x**4 + 368.816080918066*x**3 - 20.500262217588*x**2 + 0.545840273670868*x + 0.0590464366057008

v = np.linspace(0, 2*np.pi, 60)
U, V = np.meshgrid(u, v)

X = U
Y1 = polynomial(X)*np.cos(V)
Z1 = polynomial(X)*np.sin(V)

# Revolving around the axis
Y2 = 0*np.cos(V)
Z2 = 0*np.sin(V)

ax.plot_surface(X, Y1, Z1, alpha=0.3, color='red', rstride=6, cstride=12)
ax.plot_surface(X, Y2, Z2, alpha=0.3, color='blue', rstride=6, cstride=12)

# set the limits of the axes
ax.set_xlim3d(-0.3, 0.3) 
ax.set_ylim3d(-0.3, 0.3) 
ax.set_zlim3d(-0.3, 0.3) 

plt.show()

enter image description here

Derek O
  • 16,770
  • 4
  • 24
  • 43