# Plotting families (depending on integer parameter(s)) of curvilinear coordinate and isolevel lines and surfaces, resp. for functional and parametric surfaces, and for 3-variate scalar fields and volume deformations in 3D

Anonymous

To begin with a warning: I am a very experienced mathematician but a complete – 'greenhorn' – beginner in SAGE. I would like to be able to plot in the same 3D plot FAMILIES OF PARAMETRIC CURVES IN 3D (x(i)=x(t,i),y=y(t,i),z=z(t,i)) plotted via e.g. parametric_plot3D DEPENDING ON A NON-NEGATIVE INTEGER PARAMETER i in range(I+1) where the coordinate functions x,y,z are defined as functions of t by me and are not necessarily predefined SAGE functions, and where I can vary the non-negative integer I without varying the code. I would like to do the same for FAMILIES OF FUNCTIONAL SURFACES (z=f(x,y,i), DEPENDING ON A NON-NEGATIVE INTEGER PARAMETER i) using e.g. ParametricSurface, as well as TO DO THE SAME for FAMILIES OF PARAMETRIC SURFACES ( (fx(u,v,i),fy(u,v,i),fz(u,v,i)) ) via using e.g. parametric_plot3D DEPENDING ON A NON-NEGATIVE INTEGER PARAMETER i in range(I+1. I would also like to be able to do the same for FAMILIES OF IMPLICITLY DEFINED SURFACES IN 3D DEPENDING ON A NON-NEGATIVE INTEGER PARAMETER i, using e.g. implicit_plot3d ( (f(x,y,z)-C(i)==0, I in range (I+1)), C being a 1-dimensional array (in general algorithmic language) with entries – real numbers in the range of the values of the real-valued f), with the possibility of custom definition of f, I and C. Examining the SAGE tutorials and reference manuals, I have so far been able to find a model solution of this problem only for planar curves in 2D using plot() and only for SAGE-predefined curves (namely, polynomial curves): http://sage.maa.org/home/pub/140/

sage: lotsa_plots = sum([plot(x^n,(x,0,1),color=rainbow(5)[n]) for n in range(5)]) Already in this simple 2D case, if the SAGE-predefined function x^n in the above example be replaced by a custom-defined function f(x,n) , it is not clear to me (a greenhorn!) how to extend the above instance to plotting together the 2D graphs of f(x,n), color=rainbow(N)[n]) for n in range(N), where one should be able to vary N withouth modifying the SAGE code. I think that providing examples solving the above tasks in the SAGE tutorials/manuals (or developing SAGE in this direction if the tasks are currently SAGE-unsolvable!) is of key importance FOR A GREAT MANY OF THE USERS (OR WANNABE USERS) OF SAGE WHO ARE EXPERIENCED THEORETICIANS BUT ARE NOT EXPERIENCED PROGRAMMERS. To facilitate the eventual answering of these questions, I herewith propose a simple but comprehensive example. IF YOU PROVIDE COMPLETE ANSWERS CONCERNING THIS EXAMPLE, YOU WILL HAVE ANSWERED ALL OF THE ABOVE QUESTIONS TOGETHER. Moreover, your answer would certainly merit to be included among the examples in the next version(s) of the SAGE tutorial[(s) and/or reference manual(s).
Consider the 3D scalar field (argument is a 3D vector ...

edit retag close merge delete

It is not very easy to read the question. Would you mind editing using LaTeX syntax and indenting code blocks? ps Is this the longest question we have seen aruond ask.sagemath?

( 2015-10-08 16:46:53 +0200 )edit

Sort by » oldest newest most voted

I believe that the following (tested) code provides a simple, yet complete answer to my question:

First, for functional surfaces (z=f(x,y)), the following code provides an alternative to the solution invoking the class ParametrizedSurface3D: here we only use parametric_plot3d:

M=5
funcsurfplot=[0 for i in range(M)]
x, y = var ('x, y', domain='real')
n=var('n', domain='integer')
funcsurfplot=[parametric_plot3d((x, y, exp(-(x^2+y^2)/(n+1))), \                                                                                         (x, -2-n, 2+n), (y, -2-n, 2+n), \                                                                                                                                     color=rainbow(M)[n], opacity=0.3,  mesh=True) for n in range(M)]
P=sum(funcsurfplot[i] for i in range(M))
P.show(viewer='jmol')


Note that in this case we have full control over the domains of each of the functions in the family of surfaces, and that these domains can also depend on the integer parameter of the family. The line "funcsurfplot=[0 for i in range(M)]" might be considered redundant, but I prefer it for creation of array-like list in Python with custom size, because, unlike the use of 'append', this approach allows the easy construction of multidimensional arrays (two dimensional arrays would be needed for visualizing the families of coordinate surfaces in the example I gave in the formulation of the question) -- see, e.g.,

http://www.i-programmer.info/programm...

Now all the other cases of the question can be resolved in the same simple uniform way, as follows:

Second, meshes of 3D curves (curvilinear coordinates in 3D and on surfaces):

M=5
curve3dplot=[0 for i in range(M)] # creation of array of size M+1 via initialization
t=var ('t', domain='real')
n=var('n', domain='integer')
curve3dplot=[parametric_plot3d((exp(-(n+t)^2), cos(n*t*pi), 1/(1+n*t^2)),  (t, -1, 1), \                                 color=rainbow(M)[n], thickness=4) for n in range(M)]
P=sum(curve3dplot[i] for i in range(M))
P.show(viewer='jmol')


Third, families of parametric surfaces (the surfaces chosen here are Klein bottles of the default type in SAGE - see

http://doc.sagemath.org/html/en/refer...

and, in order to introduce dependence on n also in the parametric domains, I have slightly 'unzipped' them):

M=5
parasurf3dplot=[0 for i in range(M)]
u, v = var ('u, v', domain='real')
n=var('n', domain='integer')
def fx(u,v,n): return ((n+1)/M+cos(u/2)*cos(v)-sin(u/2)*sin(2*v))*cos(u)
def fy(u,v,n): return ((n+1)/M+cos(u/2)*cos(v)-sin(u/2)*sin(2*v))*sin(u)
def fz(u,v,n): return sin(u/2)*cos(v)+cos(u/2)*sin(2*v)
def rangeu(n): return (u, -pi+(n/M^3)*pi,pi-(n/M^3)*pi)
def rangev(n): return (v, -pi+(n/M^3)*pi,pi-(n/M^3)*pi)
parasurf3dplot=[parametric_plot3d((fx(u,v,n), fy(u,v,n), fz(u,v,n)), rangeu(n), rangev(n), \        color=rainbow(M)[n], opacity=0 ...
more

One suggestion would be to use

M=10
surfaces = [ParametrizedSurface3D( (x,y,exp(-(x^2+y^2)/n)), (x,y)) for n in range(1,M+1)]
plot = sum([ s.plot(color=rainbow(M)[i],opacity=0.5) for i,s in enumerate(surfaces)])
plot.show()


Just learned that ParametrizedSurface3D is a surface object, not a plot. So we first create the surfaces and then we render the plot, which will be the sum of all plots of the previously defined surfaces. I guess you can replace exp(-(x^2+y^2)/n by any other function, but that is just a guess.

more

Thank you for your kind response and the proposed solution, fidbc. I tested it and it works properly and is a good starting point. However, to solve the problem of designing and plotting arbitrary parametric meshes (which is implemented, say, in Mathematica) we need more. First, we need to have control over the range of parameters; second, it is somehow unnatural to use for plotting a class (ParametrizedSurface3D) relevant to the intrinsic geometry of the surface rather than the class(es) designed for its plotting; third, some of the visualization classes mentioned in my question do not have an attribute 'plot' but only 'show'.

( 2015-10-11 03:59:25 +0200 )edit

In continuation of my comment, what we need is a simple uniform way of using the two visualization classes: 1. parametric_plot3d for meshes of lines (curvilinear coordinates (fx(t),fy(t),fz(t))), for families of functional surfaces (x,y,f(x,y)) and for families of parametric surfaces (fx(u,v),fy(u,v),fz(u,v)), and 2. implicit_plot3d for families of isosurfaces ( F(x,y,z)==0). After reading your reply and proposed solution, I dug a bit into Python's lists' use as arrays, and found such a simple uniform general answer about the design of arbitrary meshes using the already available tools in SAGE. I will post the respective tested code in updating my 'answer' given below, right after this comment.

( 2015-10-11 04:19:07 +0200 )edit