我有贝塞尔曲线,我需要根据该曲线制作旋转曲面。贝塞尔曲线应围绕旋转轴旋转。怎么做?也许有一些例子?点可以固定,但只能固定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
主要部分
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:我在这项任务上做了一些事情。但这并不是我真正需要的,现在有很多行,而不是表面。我试图做一个表面,但是失败了
Upd2: 这是我尝试进行革命的尝试,但也失败了
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