Boundaries for parametric_plot3d?
Is it possible to specify the bounding box of the output of a call to parametric_plot3d?
I am trying to produce animations of Frenet frames. The following code 'works' more or less, but in each frame sage changes the bounding box slightly, producing less than ideal results. If I have to resort to plotting some kind of bounding object with opacity set to 0, then so be it, but I am hoping for a more elegant solution.
t = var('t')
x(t) = (cos(3*t)+2)*cos(2*t)
y(t) = (cos(3*t)+2)*sin(2*t)
z(t) = -sin(3*t)
gamma = vector([x,y,z])
def length(v):
return sqrt(v[0]^2+v[1]^2+v[2]^2)
a = 0
b = 2*pi
P = parametric_plot3d(gamma(t),(t,a,b),frame=False)
T = gamma.diff(t)/length(gamma.diff(t))
N = T.diff(t)/length(T.diff(t))
B = T.cross_product(N)
def frame(t):
return P + arrow(gamma(t),gamma(t)+T(t),color='green',frame=False) + arrow(gamma(t),gamma(t)+N(t),color='red',frame=False) + arrow(gamma(t),gamma(t)+B(t),color='purple',frame=False)
num_frames = 10
frenet_movie = animate([frame(tt) for tt in srange(a,b,(b-a)/num_frames)])
frenet_movie.show()
(You can up num_frames if you want a smoother movie, though these take a while to render. The length function is defined because the normalized()
method was producing lots of strange errors, namely with sage claiming it could not produce numerical approximations of the vectors involved....)
The camera position is set internally (I forget where at the moment -- it's not obvious at first glance). I've looked into this before, and recall finding no convenient way to override the automatic defaults. So a zero-opacity bounding object(s) is probably the most elegant solution :/