def new_plot3d( f, xmin, xmax, ymin, ymax, zmin, zmax, **kwargs ):
r"""
This function provides a 3D plot of a function z=f(x,y) but in
a restricted domain given by xmin < x < xmax, ymin < y < ymax, and
zmin < z < zmax. It also computes the correct aspect ratio to make
the 3D plot appear in a cube. Note, if the widths of the intervals
on x, y and z, are not the same length, then this will distort
angles and some distances. Yet, this usually produces a very visually
appealling 3D graph.
Example:
var("x y z")
new_plot3d( x^3-y^4, -2,2,-2,2,-4,4 )
The options color, plot_points, mesh, opacity, and aspect_ratio
are available from implicit_plot3d(). Moreover, the options viewer,
width, and possibly others are available from show().
"""
assert xmin < xmax
assert ymin < ymax
assert zmin < zmax
xwide = xmax - xmin
ywide = ymax - ymin
zwide = zmax - zmin
kwargs['mesh'] = kwargs.get('mesh', True )
kwargs['plot_points'] = kwargs.get('plot_points', 25)
kwargs['color'] = kwargs.get('color', 'seagreen')
kwargs['aspect_ratio'] = kwargs.get('aspect_ratio', [1/xwide, 1/ywide, 1/zwide] )
var("x y z")
P = implicit_plot3d( z == f(x,y), (x,xmin,xmax), (y,ymin,ymax), (z,zmin,zmax), **kwargs )
return P
def new_complex_plot3d( f, xmin, xmax, ymin, ymax, zmin, zmax, style, **kwargs ):
"""This plots a function whose sole input is a complex number, and whose sole
output is a complex number. There are many ways to plot such a function, and
they are chosen with the parameter style.
The options for style are 'magnitude', 'real', 'imaginary', 'argument', or 'mixed'.
Also 'phase' is a synonym for 'argument'.
Consider the function to be plotted as f(s) = f(x+iy). To be clear, the input to
the complex-function f is s=x+iy. The 3D plot has an x-axis, a y-axis, and a z-axis.
The x-axis is always the real part of the input, and the y-axis is always the
imaginary part of the input. The z-axis is determined by the choice of style.
For 'magnitude' it is the magnitude or norm of the output of f(s) = f(x+iy).
For 'real' it is the real part of the output of f(s) = f(x+iy).
For 'imaginary' it is the imaginary part of the output of f(s) = f(x+iy).
For 'argument' or 'phase' it is the argument/phase of the output of f(s) = f(x+iy).
(In other words, if you think of the complex number in polar coordinates, it is the
theta of the output, in the sense of x+iy = rho*(cos(theta) + i*sin(theta)). The
rho is the magnitude.
"""
g(x,y) = f( x + i*y )
if ( (style=='magnitude') or (style=='Magnitude') or (style=='MAGNITUDE') ):
real_g(x,y) = real_part( g(x,y) )
imag_g(x,y) = imag_part( g(x,y) )
answer(x,y) = sqrt( real_g(x,y)^2 + imag_g(x,y)^2 )
elif ( (style=='real') or (style=='Real') or (style=='REAL') ):
answer(x,y) = real_part( g(x,y) )
elif ( (style=='imaginary') or (style=='Imaginary') or (style=='IMAGINARY')
or (style=='imag') or (style=='Imag') or (style=='IMAG')):
answer(x,y) = imag_part( g(x,y) )
elif ( (style=='argument') or (style=='Argument') or (style=='ARGUMENT')
or (style=='phase') or (style=='Phase') or (style=='PHASE')):
return newComplexArgumentPlot3d( f, xmin, xmax, ymin, ymax, zmin, zmax, **kwargs )
elif ( (style=='mixed') or (style=='Mixed') or (style=='MIXED')):
real_g(x,y) = real_part( g(x,y) )
imag_g(x,y) = imag_part( g(x,y) )
answer(x,y) = sqrt( real_g(x,y)^2 + imag_g(x,y)^2 )
T = lambda x,y,z : ( CC( g(x=x,y=y) ).argument() + N(pi) ) / (2*N(pi))
new_color_option = (T, colormaps.gist_rainbow)
kwargs['color'] = new_color_option
kwargs['viewer'] = 'tachyon'
return new_plot3d( answer(x,y), xmin, xmax, ymin, ymax, zmin, zmax, **kwargs )
else:
assert false, "I have no idea what you are asking me for."
P = new_plot3d( answer(x,y), xmin, xmax, ymin, ymax, zmin, zmax, **kwargs )
return P