I have Bezier curve and I need to make surface of revolution based on this curve. Bezier curve should be rotating around an axis of rotation. How it can be done? Maybe some examples? Dots can be fixed, but only 3
import matplotlib as mpl
import numpy as np
from scipy.misc import comb
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import math
import pylab
def bernstein_poly(i, n, t):
return comb(n, i) * (t**(n - i)) * (1 - t)**i
def bezier_curve(points, nTimes=1000):
nPoints = len(points)
xPoints = np.array([p[0] for p in points])
yPoints = np.array([p[1] for p in points])
zPoints = np.array([p[2] for p in points])
t = np.linspace(0.0, 1.0, nTimes)
polynomial_array = np.array(
[bernstein_poly(i, nPoints - 1, t) for i in range(0, nPoints)])
xvals = np.dot(xPoints, polynomial_array)
yvals = np.dot(yPoints, polynomial_array)
zvals = np.dot(zPoints, polynomial_array)
return xvals, yvals, zvals
from math import pi ,sin, cos
def R(theta, u):
return [[cos(theta) + u[0]**2 * (1-cos(theta)),
u[0] * u[1] * (1-cos(theta)) - u[2] * sin(theta),
u[0] * u[2] * (1 - cos(theta)) + u[1] * sin(theta)],
[u[0] * u[1] * (1-cos(theta)) + u[2] * sin(theta),
cos(theta) + u[1]**2 * (1-cos(theta)),
u[1] * u[2] * (1 - cos(theta)) - u[0] * sin(theta)],
[u[0] * u[2] * (1-cos(theta)) - u[1] * sin(theta),
u[1] * u[2] * (1-cos(theta)) + u[0] * sin(theta),
cos(theta) + u[2]**2 * (1-cos(theta))]]
def Rotate(pointToRotate, point1, point2, theta):
u= []
squaredSum = 0
for i,f in zip(point1, point2):
u.append(f-i)
squaredSum += (f-i) **2
u = [i/squaredSum for i in u]
r = R(theta, u)
rotated = []
for i in range(3):
rotated.append(round(sum([r[j][i] * pointToRotate[j] for j in range(3)])))
return rotated
And main part
if __name__ == "__main__":
nPoints = 3
points = [[0,0,0],[0,1,2],[0,2,1]]#3 points of curve
xvals, yvals, zvals = bezier_curve(points, nTimes=1000)
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot(xvals, yvals, zvals, label='bezier')
p1=[0,0,0]#axis of rotation
p2=[0,0,1]#axis of rotation
angle = pi/12
while angle <= 2*pi:
pp1 = Rotate(points[0], p1, p2, angle)
pp2 = Rotate(points[1], p1, p2, angle)
pp3 = Rotate(points[2], p1, p2, angle)
npoints=[pp1,pp2,pp3]
xnvals, ynvals, znvals = bezier_curve(npoints, nTimes=1000)
ax.plot(xnvals, ynvals, znvals, label='bezier')
angle= angle + pi/24
plt.show()
upd: I do something on this task. But this is not exactly what I need.Now its many lines, not surface. I tried to make a surface, but failed
Upd2: This is my attempt to make surface of revolution, but its failed too
x = np.arange (0, 0.1, 0.005)
y = np.arange (0, 0.1, 0.005)
xgrid, ygrid = np.meshgrid(x, y)
points = [[0,0,0],[0,1,2],[0,2,1]] #Bezier curve points
p1=[0,0,0]#axis of rotation
p2=[0,0,1]#axis of rotation
angle = pi/12
xval, yval, zval = bezier_curve(points, nTimes=20)
x=xgrid
y=ygrid
z=zval
fig = pylab.figure()
axes = Axes3D(fig)
axes.plot_surface(x, y, z)
while angle <= 2*pi:
pp1 = Rotate(points[0], p1, p2, angle)
pp2 = Rotate(points[1], p1, p2, angle)
pp3 = Rotate(points[2], p1, p2, angle)
npoints=[pp1,pp2,pp3]
x = np.arange (0, 0.1, 0.005)
y = np.arange (0, 0.1, 0.005)
xgrid, ygrid = np.meshgrid(x, y)
xval, yval, zval = bezier_curve(npoints, nTimes=20)
zgrid= zval
x=xgrid
y=ygrid
z=zgrid
axes.plot_surface(x, y, z)
angle= angle + pi/24