passagemath-plot 10.6.31rc3__cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of passagemath-plot might be problematic. Click here for more details.

Files changed (81) hide show
  1. passagemath_plot-10.6.31rc3.dist-info/METADATA +172 -0
  2. passagemath_plot-10.6.31rc3.dist-info/RECORD +81 -0
  3. passagemath_plot-10.6.31rc3.dist-info/WHEEL +6 -0
  4. passagemath_plot-10.6.31rc3.dist-info/top_level.txt +2 -0
  5. passagemath_plot.libs/libgfortran-e1b7dfc8.so.5.0.0 +0 -0
  6. passagemath_plot.libs/libgsl-e3525837.so.28.0.0 +0 -0
  7. passagemath_plot.libs/libopenblasp-r0-4c5b64b1.3.29.so +0 -0
  8. sage/all__sagemath_plot.py +15 -0
  9. sage/ext_data/threejs/animation.css +195 -0
  10. sage/ext_data/threejs/animation.html +85 -0
  11. sage/ext_data/threejs/animation.js +273 -0
  12. sage/ext_data/threejs/fat_lines.js +48 -0
  13. sage/ext_data/threejs/threejs-version.txt +1 -0
  14. sage/ext_data/threejs/threejs_template.html +597 -0
  15. sage/interfaces/all__sagemath_plot.py +1 -0
  16. sage/interfaces/gnuplot.py +196 -0
  17. sage/interfaces/jmoldata.py +208 -0
  18. sage/interfaces/povray.py +56 -0
  19. sage/plot/all.py +42 -0
  20. sage/plot/animate.py +1796 -0
  21. sage/plot/arc.py +504 -0
  22. sage/plot/arrow.py +671 -0
  23. sage/plot/bar_chart.py +205 -0
  24. sage/plot/bezier_path.py +400 -0
  25. sage/plot/circle.py +435 -0
  26. sage/plot/colors.py +1606 -0
  27. sage/plot/complex_plot.cpython-314-aarch64-linux-gnu.so +0 -0
  28. sage/plot/complex_plot.pyx +1446 -0
  29. sage/plot/contour_plot.py +1792 -0
  30. sage/plot/density_plot.py +318 -0
  31. sage/plot/disk.py +373 -0
  32. sage/plot/ellipse.py +375 -0
  33. sage/plot/graphics.py +3580 -0
  34. sage/plot/histogram.py +354 -0
  35. sage/plot/hyperbolic_arc.py +404 -0
  36. sage/plot/hyperbolic_polygon.py +416 -0
  37. sage/plot/hyperbolic_regular_polygon.py +296 -0
  38. sage/plot/line.py +626 -0
  39. sage/plot/matrix_plot.py +629 -0
  40. sage/plot/misc.py +509 -0
  41. sage/plot/multigraphics.py +1294 -0
  42. sage/plot/plot.py +4183 -0
  43. sage/plot/plot3d/all.py +23 -0
  44. sage/plot/plot3d/base.cpython-314-aarch64-linux-gnu.so +0 -0
  45. sage/plot/plot3d/base.pxd +12 -0
  46. sage/plot/plot3d/base.pyx +3378 -0
  47. sage/plot/plot3d/implicit_plot3d.py +659 -0
  48. sage/plot/plot3d/implicit_surface.cpython-314-aarch64-linux-gnu.so +0 -0
  49. sage/plot/plot3d/implicit_surface.pyx +1453 -0
  50. sage/plot/plot3d/index_face_set.cpython-314-aarch64-linux-gnu.so +0 -0
  51. sage/plot/plot3d/index_face_set.pxd +32 -0
  52. sage/plot/plot3d/index_face_set.pyx +1873 -0
  53. sage/plot/plot3d/introduction.py +131 -0
  54. sage/plot/plot3d/list_plot3d.py +649 -0
  55. sage/plot/plot3d/parametric_plot3d.py +1130 -0
  56. sage/plot/plot3d/parametric_surface.cpython-314-aarch64-linux-gnu.so +0 -0
  57. sage/plot/plot3d/parametric_surface.pxd +12 -0
  58. sage/plot/plot3d/parametric_surface.pyx +893 -0
  59. sage/plot/plot3d/platonic.py +601 -0
  60. sage/plot/plot3d/plot3d.py +1442 -0
  61. sage/plot/plot3d/plot_field3d.py +162 -0
  62. sage/plot/plot3d/point_c.pxi +148 -0
  63. sage/plot/plot3d/revolution_plot3d.py +309 -0
  64. sage/plot/plot3d/shapes.cpython-314-aarch64-linux-gnu.so +0 -0
  65. sage/plot/plot3d/shapes.pxd +22 -0
  66. sage/plot/plot3d/shapes.pyx +1382 -0
  67. sage/plot/plot3d/shapes2.py +1512 -0
  68. sage/plot/plot3d/tachyon.py +1779 -0
  69. sage/plot/plot3d/texture.py +453 -0
  70. sage/plot/plot3d/transform.cpython-314-aarch64-linux-gnu.so +0 -0
  71. sage/plot/plot3d/transform.pxd +21 -0
  72. sage/plot/plot3d/transform.pyx +268 -0
  73. sage/plot/plot3d/tri_plot.py +589 -0
  74. sage/plot/plot_field.py +362 -0
  75. sage/plot/point.py +624 -0
  76. sage/plot/polygon.py +562 -0
  77. sage/plot/primitive.py +249 -0
  78. sage/plot/scatter_plot.py +199 -0
  79. sage/plot/step.py +85 -0
  80. sage/plot/streamline_plot.py +328 -0
  81. sage/plot/text.py +432 -0
@@ -0,0 +1,1130 @@
1
+ # sage_setup: distribution = sagemath-plot
2
+ # sage.doctest: needs sage.symbolic
3
+ """
4
+ Parametric plots
5
+ """
6
+
7
+ from .parametric_surface import ParametricSurface
8
+ from .shapes2 import line3d
9
+ from sage.arith.srange import xsrange, srange
10
+ from sage.structure.element import Vector
11
+ from sage.misc.decorators import rename_keyword
12
+
13
+
14
+ @rename_keyword(alpha='opacity')
15
+ def parametric_plot3d(f, urange, vrange=None, plot_points='automatic',
16
+ boundary_style=None, **kwds):
17
+ r"""
18
+ Return a parametric three-dimensional space curve or surface.
19
+
20
+ There are four ways to call this function:
21
+
22
+ - ``parametric_plot3d([f_x, f_y, f_z], (u_min, u_max))``:
23
+ `f_x, f_y, f_z` are three functions and
24
+ `u_{\min}` and `u_{\max}` are real numbers
25
+
26
+ - ``parametric_plot3d([f_x, f_y, f_z], (u, u_min, u_max))``:
27
+ `f_x, f_y, f_z` can be viewed as functions of
28
+ `u`
29
+
30
+ - ``parametric_plot3d([f_x, f_y, f_z], (u_min, u_max),
31
+ (v_min, v_max))``:
32
+ `f_x, f_y, f_z` are each functions of two variables
33
+
34
+ - ``parametric_plot3d([f_x, f_y, f_z], (u, u_min, u_max), (v, v_min, v_max))``:
35
+ `f_x, f_y, f_z` can be viewed as functions of
36
+ `u` and `v`
37
+
38
+
39
+ INPUT:
40
+
41
+ - ``f`` -- a 3-tuple of functions or expressions, or vector of size 3
42
+
43
+ - ``urange`` -- a 2-tuple (u_min, u_max) or a 3-tuple
44
+ (u, u_min, u_max)
45
+
46
+ - ``vrange`` -- (optional, only used for surfaces) a
47
+ 2-tuple (v_min, v_max) or a 3-tuple (v, v_min, v_max)
48
+
49
+ - ``plot_points`` -- (default: "automatic", which is
50
+ 75 for curves and [40,40] for surfaces) initial number of sample
51
+ points in each parameter; an integer for a curve, and a pair of
52
+ integers for a surface.
53
+
54
+ - ``boundary_style`` -- (default: None, no boundary) a dict that describes
55
+ how to draw the boundaries of regions by giving options that are passed
56
+ to the line3d command.
57
+
58
+ - ``mesh`` -- boolean (default: ``False``); whether to display
59
+ mesh grid lines
60
+
61
+ - ``dots`` -- boolean (default: ``False``); whether to display
62
+ dots at mesh grid points
63
+
64
+ .. NOTE::
65
+
66
+ #. By default for a curve any points where `f_x`,
67
+ `f_y`, or `f_z` do not evaluate to a real number
68
+ are skipped.
69
+
70
+ #. Currently for a surface `f_x`, `f_y`, and
71
+ `f_z` have to be defined everywhere. This will change.
72
+
73
+ #. mesh and dots are not supported when using the Tachyon ray tracer
74
+ renderer.
75
+
76
+ EXAMPLES: We demonstrate each of the four ways to call this
77
+ function.
78
+
79
+
80
+ #. A space curve defined by three functions of 1 variable:
81
+
82
+ ::
83
+
84
+ sage: parametric_plot3d((sin, cos, lambda u: u/10), (0,20))
85
+ Graphics3d Object
86
+
87
+
88
+ .. PLOT::
89
+
90
+ sphinx_plot(parametric_plot3d((sin, cos, lambda u: u/10), (0,20)))
91
+
92
+ Note above the lambda function, which creates a callable Python
93
+ function that sends `u` to `u/10`.
94
+
95
+ #. Next we draw the same plot as above, but using symbolic
96
+ functions:
97
+
98
+ ::
99
+
100
+ sage: u = var('u')
101
+ sage: parametric_plot3d((sin(u), cos(u), u/10), (u,0,20))
102
+ Graphics3d Object
103
+
104
+
105
+ .. PLOT::
106
+
107
+ u = var('u')
108
+ sphinx_plot(parametric_plot3d((sin(u), cos(u), u/10), (u,0,20)))
109
+
110
+ #. We draw a parametric surface using 3 Python functions (defined
111
+ using lambda):
112
+
113
+ ::
114
+
115
+ sage: f = (lambda u,v: cos(u), lambda u,v: sin(u)+cos(v), lambda u,v: sin(v))
116
+ sage: parametric_plot3d(f, (0,2*pi), (-pi,pi))
117
+ Graphics3d Object
118
+
119
+
120
+ .. PLOT::
121
+
122
+ f = (lambda u,v: cos(u), lambda u,v: sin(u)+cos(v), lambda u,v: sin(v))
123
+ sphinx_plot(parametric_plot3d(f, (0,2*pi), (-pi,pi)))
124
+
125
+ #. The same surface, but where the defining functions are
126
+ symbolic:
127
+
128
+ ::
129
+
130
+ sage: u, v = var('u,v')
131
+ sage: parametric_plot3d((cos(u), sin(u)+cos(v), sin(v)), (u,0,2*pi), (v,-pi,pi))
132
+ Graphics3d Object
133
+
134
+
135
+ .. PLOT::
136
+
137
+ u, v = var('u,v')
138
+ sphinx_plot(parametric_plot3d((cos(u), sin(u)+cos(v) ,sin(v)), (u,0,2*pi), (v,-pi,pi)))
139
+
140
+ The surface, but with a mesh::
141
+
142
+ sage: u, v = var('u,v')
143
+ sage: parametric_plot3d((cos(u), sin(u)+cos(v), sin(v)), (u,0,2*pi), (v,-pi,pi), mesh=True)
144
+ Graphics3d Object
145
+
146
+
147
+ .. PLOT::
148
+
149
+ u, v = var('u,v')
150
+ sphinx_plot(parametric_plot3d((cos(u), sin(u)+cos(v), sin(v)), (u,0,2*pi), (v,-pi,pi), mesh=True))
151
+
152
+ We increase the number of plot points, and make the surface green
153
+ and transparent::
154
+
155
+ sage: parametric_plot3d((cos(u), sin(u)+cos(v), sin(v)), (u,0,2*pi), (v,-pi,pi),
156
+ ....: color='green', opacity=0.1, plot_points=[30,30])
157
+ Graphics3d Object
158
+
159
+ .. PLOT::
160
+
161
+ u, v = var('u,v')
162
+ sphinx_plot(parametric_plot3d((cos(u), sin(u)+cos(v), sin(v)), (u,0,2*pi), (v,-pi,pi),
163
+ color='green', opacity=0.1, plot_points=[30,30]))
164
+
165
+ One can also color the surface using a coloring function and a
166
+ colormap as follows. Note that the coloring function must take
167
+ values in the interval [0,1]. ::
168
+
169
+ sage: u,v = var('u,v')
170
+ sage: def cf(u, v): return sin(u+v/2)**2
171
+ sage: P = parametric_plot3d((cos(u), sin(u)+cos(v), sin(v)),
172
+ ....: (u,0,2*pi), (v,-pi,pi), color=(cf,colormaps.PiYG), plot_points=[60,60])
173
+ sage: P.show(viewer='tachyon')
174
+
175
+ .. PLOT::
176
+
177
+ u,v = var('u,v')
178
+ def cf(u, v): return sin(u+v/2)**2
179
+ P = parametric_plot3d((cos(u), sin(u)+cos(v), sin(v)),
180
+ (u,0,2*pi), (v,-pi,pi), color=(cf,colormaps.PiYG), plot_points=[60,60])
181
+ sphinx_plot(P)
182
+
183
+ Another example, a colored Möbius band::
184
+
185
+ sage: cm = colormaps.ocean
186
+ sage: def c(x, y): return sin(x*y)**2
187
+ sage: from sage.plot.plot3d.parametric_surface import MoebiusStrip
188
+ sage: MoebiusStrip(5, 1, plot_points=200, color=(c,cm))
189
+ Graphics3d Object
190
+
191
+ .. PLOT::
192
+
193
+ cm = colormaps.ocean
194
+ def c(x, y): return sin(x*y)**2
195
+ from sage.plot.plot3d.parametric_surface import MoebiusStrip
196
+ sphinx_plot(MoebiusStrip(5, 1, plot_points=200, color=(c,cm)))
197
+
198
+ Yet another colored example::
199
+
200
+ sage: from sage.plot.plot3d.parametric_surface import ParametricSurface
201
+ sage: cm = colormaps.autumn
202
+ sage: def c(x, y): return sin(x*y)**2
203
+ sage: def g(x, y): return x, y+sin(y), x**2 + y**2
204
+ sage: ParametricSurface(g, (srange(-10,10,0.1), srange(-5,5.0,0.1)), color=(c,cm))
205
+ Graphics3d Object
206
+
207
+ .. PLOT::
208
+
209
+ from sage.plot.plot3d.parametric_surface import ParametricSurface
210
+ cm = colormaps.autumn
211
+ def c(x, y): return sin(x*y)**2
212
+ def g(x, y): return x, y+sin(y), x**2 + y**2
213
+ sphinx_plot(ParametricSurface(g, (srange(-10,10,0.1), srange(-5,5.0,0.1)), color=(c,cm)))
214
+
215
+ We call the space curve function but with polynomials instead of
216
+ symbolic variables.
217
+
218
+ ::
219
+
220
+ sage: R.<t> = RDF[]
221
+ sage: parametric_plot3d((t, t^2, t^3), (t,0,3))
222
+ Graphics3d Object
223
+
224
+ .. PLOT::
225
+
226
+ t = var('t')
227
+ R = RDF['t']
228
+ sphinx_plot(parametric_plot3d((t, t**2, t**3), (t,0,3)))
229
+
230
+ Next we plot the same curve, but because we use (0, 3) instead of
231
+ (t, 0, 3), each polynomial is viewed as a callable function of one
232
+ variable::
233
+
234
+ sage: parametric_plot3d((t, t^2, t^3), (0,3))
235
+ Graphics3d Object
236
+
237
+ .. PLOT::
238
+
239
+ t = var('t')
240
+ R = RDF['t']
241
+ sphinx_plot(parametric_plot3d((t, t**2, t**3), (0,3)))
242
+
243
+ We do a plot but mix a symbolic input, and an integer::
244
+
245
+ sage: t = var('t')
246
+ sage: parametric_plot3d((1, sin(t), cos(t)), (t,0,3))
247
+ Graphics3d Object
248
+
249
+ .. PLOT::
250
+
251
+ t = var('t')
252
+ sphinx_plot(parametric_plot3d((1, sin(t), cos(t)), (t,0,3)))
253
+
254
+ We specify a boundary style to show us the values of the function at its
255
+ extrema::
256
+
257
+ sage: u, v = var('u,v')
258
+ sage: parametric_plot3d((cos(u), sin(u)+cos(v), sin(v)), (u,0,pi), (v,0,pi),
259
+ ....: boundary_style={"color": "black", "thickness": 2})
260
+ Graphics3d Object
261
+
262
+ .. PLOT::
263
+
264
+ u, v = var('u,v')
265
+ P = parametric_plot3d((cos(u), sin(u)+cos(v), sin(v)), (u,0,pi), (v,0,pi),
266
+ boundary_style={"color":"black", "thickness":2})
267
+ sphinx_plot(P)
268
+
269
+ We can plot vectors::
270
+
271
+ sage: x,y = var('x,y')
272
+ sage: parametric_plot3d(vector([x-y, x*y, x*cos(y)]), (x,0,2), (y,0,2))
273
+ Graphics3d Object
274
+
275
+ .. PLOT::
276
+
277
+ x,y = var('x,y')
278
+ sphinx_plot(parametric_plot3d(vector([x-y, x*y, x*cos(y)]), (x,0,2), (y,0,2)))
279
+
280
+ ::
281
+
282
+ sage: t = var('t')
283
+ sage: p = vector([1,2,3])
284
+ sage: q = vector([2,-1,2])
285
+ sage: parametric_plot3d(p*t+q, (t,0,2))
286
+ Graphics3d Object
287
+
288
+ .. PLOT::
289
+
290
+ t = var('t')
291
+ p = vector([1,2,3])
292
+ q = vector([2,-1,2])
293
+ sphinx_plot(parametric_plot3d(p*t+q, (t,0,2)))
294
+
295
+ Any options you would normally use to specify the appearance of a curve are
296
+ valid as entries in the ``boundary_style`` dict.
297
+
298
+ MANY MORE EXAMPLES:
299
+
300
+ We plot two interlinked tori::
301
+
302
+ sage: u, v = var('u,v')
303
+ sage: f1 = (4+(3+cos(v))*sin(u), 4+(3+cos(v))*cos(u), 4+sin(v))
304
+ sage: f2 = (8+(3+cos(v))*cos(u), 3+sin(v), 4+(3+cos(v))*sin(u))
305
+ sage: p1 = parametric_plot3d(f1, (u,0,2*pi), (v,0,2*pi), texture='red')
306
+ sage: p2 = parametric_plot3d(f2, (u,0,2*pi), (v,0,2*pi), texture='blue')
307
+ sage: p1 + p2
308
+ Graphics3d Object
309
+
310
+ .. PLOT::
311
+
312
+ u, v = var('u,v')
313
+ f1 = (4+(3+cos(v))*sin(u), 4+(3+cos(v))*cos(u), 4+sin(v))
314
+ f2 = (8+(3+cos(v))*cos(u), 3+sin(v), 4+(3+cos(v))*sin(u))
315
+ p1 = parametric_plot3d(f1, (u,0,2*pi), (v,0,2*pi), texture='red')
316
+ p2 = parametric_plot3d(f2, (u,0,2*pi), (v,0,2*pi), texture='blue')
317
+ sphinx_plot(p1 + p2)
318
+
319
+ A cylindrical Star of David::
320
+
321
+ sage: u,v = var('u v')
322
+ sage: K = (abs(cos(u))^200+abs(sin(u))^200)^(-1.0/200)
323
+ sage: f_x = cos(u) * cos(v) * (abs(cos(3*v/4))^500+abs(sin(3*v/4))^500)^(-1/260) * K
324
+ sage: f_y = cos(u) * sin(v) * (abs(cos(3*v/4))^500+abs(sin(3*v/4))^500)^(-1/260) * K
325
+ sage: f_z = sin(u) * K
326
+ sage: parametric_plot3d([f_x, f_y, f_z], (u, -pi, pi), (v, 0, 2*pi))
327
+ Graphics3d Object
328
+
329
+ .. PLOT::
330
+
331
+ u,v = var('u v')
332
+ K = (abs(cos(u))**200+abs(sin(u))**200)**(-1.0/200)
333
+ f_x = cos(u) * cos(v) * (abs(cos(0.75*v))**500+abs(sin(0.75*v))**500)**(-1.0/260) * K
334
+ f_y = cos(u)*sin(v)*(abs(cos(0.75*v))**500+abs(sin(0.75*v))**500)**(-1.0/260) * K
335
+ f_z = sin(u) * K
336
+ P = parametric_plot3d([f_x, f_y, f_z], (u, -pi, pi), (v, 0, 2*pi))
337
+ sphinx_plot(P)
338
+
339
+ Double heart::
340
+
341
+ sage: u, v = var('u,v')
342
+ sage: G1 = abs(sqrt(2)*tanh((u/sqrt(2))))
343
+ sage: G2 = abs(sqrt(2)*tanh((v/sqrt(2))))
344
+ sage: f_x = (abs(v) - abs(u) - G1 + G2)*sin(v)
345
+ sage: f_y = (abs(v) - abs(u) - G1 - G2)*cos(v)
346
+ sage: f_z = sin(u)*(abs(cos(u)) + abs(sin(u)))^(-1)
347
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,0,pi), (v,-pi,pi))
348
+ Graphics3d Object
349
+
350
+ .. PLOT::
351
+
352
+ u, v = var('u,v')
353
+ G1 = abs(sqrt(2)*tanh((u/sqrt(2))))
354
+ G2 = abs(sqrt(2)*tanh((v/sqrt(2))))
355
+ f_x = (abs(v) - abs(u) - G1 + G2)*sin(v)
356
+ f_y = (abs(v) - abs(u) - G1 - G2)*cos(v)
357
+ f_z = sin(u)*(abs(cos(u)) + abs(sin(u)))**(-1)
358
+ sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,pi), (v,-pi,pi)))
359
+
360
+ Heart::
361
+
362
+ sage: u, v = var('u,v')
363
+ sage: f_x = cos(u)*(4*sqrt(1-v^2)*sin(abs(u))^abs(u))
364
+ sage: f_y = sin(u)*(4*sqrt(1-v^2)*sin(abs(u))^abs(u))
365
+ sage: f_z = v
366
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-1,1), frame=False, color='red')
367
+ Graphics3d Object
368
+
369
+ .. PLOT::
370
+
371
+ u, v = var('u,v')
372
+ f_x = cos(u)*(4*sqrt(1-v**2)*sin(abs(u))**abs(u))
373
+ f_y = sin(u) *(4*sqrt(1-v**2)*sin(abs(u))**abs(u))
374
+ f_z = v
375
+ sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-1,1), frame=False, color='red'))
376
+
377
+ A Trefoil knot (:wikipedia:`Trefoil_knot`)::
378
+
379
+ sage: u, v = var('u,v')
380
+ sage: f_x = (4*(1+0.25*sin(3*v))+cos(u))*cos(2*v)
381
+ sage: f_y = (4*(1+0.25*sin(3*v))+cos(u))*sin(2*v)
382
+ sage: f_z = sin(u)+2*cos(3*v)
383
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-pi,pi), frame=False, color='blue')
384
+ Graphics3d Object
385
+
386
+ .. PLOT::
387
+
388
+ u, v = var('u,v')
389
+ f_x = (4*(1+0.25*sin(3*v))+cos(u))*cos(2*v)
390
+ f_y = (4*(1+0.25*sin(3*v))+cos(u))*sin(2*v)
391
+ f_z = sin(u)+2*cos(3*v)
392
+ sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-pi,pi), frame=False, color='blue'))
393
+
394
+ Green bowtie::
395
+
396
+ sage: u, v = var('u,v')
397
+ sage: f_x = sin(u) / (sqrt(2) + sin(v))
398
+ sage: f_y = sin(u) / (sqrt(2) + cos(v))
399
+ sage: f_z = cos(u) / (1 + sqrt(2))
400
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-pi,pi), frame=False, color='green')
401
+ Graphics3d Object
402
+
403
+ .. PLOT::
404
+
405
+ u, v = var('u,v')
406
+ f_x = sin(u) / (sqrt(2) + sin(v))
407
+ f_y = sin(u) / (sqrt(2) + cos(v))
408
+ f_z = cos(u) / (1 + sqrt(2))
409
+ sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-pi,pi), frame=False, color='green'))
410
+
411
+ Boy's surface (:wikipedia:`Boy%27s_surface` and https://mathcurve.com/surfaces/boy/boy.shtml)::
412
+
413
+ sage: u, v = var('u,v')
414
+ sage: K = cos(u) / (sqrt(2) - cos(2*u)*sin(3*v))
415
+ sage: f_x = K * (cos(u)*cos(2*v)+sqrt(2)*sin(u)*cos(v))
416
+ sage: f_y = K * (cos(u)*sin(2*v)-sqrt(2)*sin(u)*sin(v))
417
+ sage: f_z = 3 * K * cos(u)
418
+ sage: parametric_plot3d([f_x, f_y, f_z], # long time
419
+ ....: (u,-2*pi,2*pi),
420
+ ....: (v,0,pi),
421
+ ....: plot_points=[90,90],
422
+ ....: frame=False,
423
+ ....: color='orange')
424
+ Graphics3d Object
425
+
426
+ .. PLOT::
427
+
428
+ u, v = var('u,v')
429
+ K = cos(u) / (sqrt(2) - cos(2*u)*sin(3*v))
430
+ f_x = K * (cos(u)*cos(2*v)+sqrt(2)*sin(u)*cos(v))
431
+ f_y = K * (cos(u)*sin(2*v)-sqrt(2)*sin(u)*sin(v))
432
+ f_z = 3 * K * cos(u)
433
+ P = parametric_plot3d([f_x, f_y, f_z], (u,-2*pi,2*pi), (v,0,pi),
434
+ plot_points=[90,90], frame=False, color='orange') # long time -- about 30 seconds
435
+ sphinx_plot(P)
436
+
437
+ Maeder's Owl also known as Bour's minimal surface (:wikipedia:`Bour%27s_minimal_surface`)::
438
+
439
+ sage: u, v = var('u,v')
440
+ sage: f_x = v*cos(u) - 0.5*v^2*cos(2*u)
441
+ sage: f_y = -v*sin(u) - 0.5*v^2*sin(2*u)
442
+ sage: f_z = 4 * v^1.5 * cos(3*u/2) / 3
443
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,-2*pi,2*pi), (v,0,1),
444
+ ....: plot_points=[90,90], frame=False, color='purple')
445
+ Graphics3d Object
446
+
447
+ .. PLOT::
448
+
449
+ u, v = var('u,v')
450
+ f_x = v*cos(u) - 0.5*v**2*cos(2*u)
451
+ f_y = -v*sin(u) - 0.5*v**2*sin(2*u)
452
+ f_z = 4 * v**1.5 * cos(3*u/2) / 3
453
+ P = parametric_plot3d([f_x, f_y, f_z], (u,-2*pi,2*pi), (v,0,1),
454
+ plot_points=[90,90], frame=False, color='purple')
455
+ sphinx_plot(P)
456
+
457
+ Bracelet::
458
+
459
+ sage: u, v = var('u,v')
460
+ sage: f_x = (2 + 0.2*sin(2*pi*u))*sin(pi*v)
461
+ sage: f_y = 0.2 * cos(2*pi*u) * 3 * cos(2*pi*v)
462
+ sage: f_z = (2 + 0.2*sin(2*pi*u))*cos(pi*v)
463
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,0,pi/2), (v,0,3*pi/4), frame=False, color='gray')
464
+ Graphics3d Object
465
+
466
+ .. PLOT::
467
+
468
+ u, v = var('u,v')
469
+ f_x = (2 + 0.2*sin(2*pi*u))*sin(pi*v)
470
+ f_y = 0.2 * cos(2*pi*u) * 3* cos(2*pi*v)
471
+ f_z = (2 + 0.2*sin(2*pi*u))*cos(pi*v)
472
+ P = parametric_plot3d([f_x, f_y, f_z], (u,0,pi/2), (v,0,3*pi/4), frame=False, color='gray')
473
+ sphinx_plot(P)
474
+
475
+
476
+ Green goblet::
477
+
478
+ sage: u, v = var('u,v')
479
+ sage: f_x = cos(u) * cos(2*v)
480
+ sage: f_y = sin(u) * cos(2*v)
481
+ sage: f_z = sin(v)
482
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,pi), frame=False, color='green')
483
+ Graphics3d Object
484
+
485
+ .. PLOT::
486
+
487
+ u, v = var('u,v')
488
+ f_x = cos(u) * cos(2*v)
489
+ f_y = sin(u) * cos(2*v)
490
+ f_z = sin(v)
491
+ sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,pi), frame=False, color='green'))
492
+
493
+
494
+ Funny folded surface - with square projection::
495
+
496
+ sage: u, v = var('u,v')
497
+ sage: f_x = cos(u) * sin(2*v)
498
+ sage: f_y = sin(u) * cos(2*v)
499
+ sage: f_z = sin(v)
500
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color='green')
501
+ Graphics3d Object
502
+
503
+ .. PLOT::
504
+
505
+ u, v = var('u,v')
506
+ f_x = cos(u) * sin(2*v)
507
+ f_y = sin(u) * cos(2*v)
508
+ f_z = sin(v)
509
+ sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color='green'))
510
+
511
+ Surface of revolution of figure 8::
512
+
513
+ sage: u, v = var('u,v')
514
+ sage: f_x = cos(u) * sin(2*v)
515
+ sage: f_y = sin(u) * sin(2*v)
516
+ sage: f_z = sin(v)
517
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color='green')
518
+ Graphics3d Object
519
+
520
+ .. PLOT::
521
+
522
+ u, v = var('u,v')
523
+ f_x = cos(u) * sin(2*v)
524
+ f_y = sin(u) * sin(2*v)
525
+ f_z = sin(v)
526
+ sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color='green'))
527
+
528
+ Yellow Whitney's umbrella (:wikipedia:`Whitney_umbrella`)::
529
+
530
+ sage: u, v = var('u,v')
531
+ sage: f_x = u*v
532
+ sage: f_y = u
533
+ sage: f_z = v^2
534
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,-1,1), (v,-1,1), frame=False, color='yellow')
535
+ Graphics3d Object
536
+
537
+ .. PLOT::
538
+
539
+ u, v = var('u,v')
540
+ f_x = u*v
541
+ f_y = u
542
+ f_z = v**2
543
+ sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-1,1), (v,-1,1), frame=False, color='yellow'))
544
+
545
+ Cross cap (:wikipedia:`Cross-cap`)::
546
+
547
+ sage: u, v = var('u,v')
548
+ sage: f_x = (1+cos(v)) * cos(u)
549
+ sage: f_y = (1+cos(v)) * sin(u)
550
+ sage: f_z = -tanh((2/3)*(u-pi)) * sin(v)
551
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color='red')
552
+ Graphics3d Object
553
+
554
+ .. PLOT::
555
+
556
+ u, v = var('u,v')
557
+ f_x = (1+cos(v)) * cos(u)
558
+ f_y = (1+cos(v)) * sin(u)
559
+ f_z = -tanh((2.0/3.0)*(u-pi)) * sin(v)
560
+ sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color='red'))
561
+
562
+ Twisted torus::
563
+
564
+ sage: u, v = var('u,v')
565
+ sage: f_x = (3+sin(v)+cos(u)) * cos(2*v)
566
+ sage: f_y = (3+sin(v)+cos(u)) * sin(2*v)
567
+ sage: f_z = sin(u) + 2*cos(v)
568
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color='red')
569
+ Graphics3d Object
570
+
571
+ .. PLOT::
572
+
573
+ u, v = var('u,v')
574
+ f_x = (3+sin(v)+cos(u)) * cos(2*v)
575
+ f_y = (3+sin(v)+cos(u)) * sin(2*v)
576
+ f_z = sin(u) + 2*cos(v)
577
+ sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color='red'))
578
+
579
+ Four intersecting discs::
580
+
581
+ sage: u, v = var('u,v')
582
+ sage: f_x = v*cos(u) - 0.5*v^2*cos(2*u)
583
+ sage: f_y = -v*sin(u) - 0.5*v^2*sin(2*u)
584
+ sage: f_z = 4 * v^1.5 * cos(3*u/2) / 3
585
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,0,4*pi), (v,0,2*pi), frame=False, color='red', opacity=0.7)
586
+ Graphics3d Object
587
+
588
+ .. PLOT::
589
+
590
+ u, v = var('u,v')
591
+ f_x = v*cos(u) - 0.5*v**2*cos(2*u)
592
+ f_y = -v*sin(u) - 0.5*v**2*sin(2*u)
593
+ f_z = 4 * v**1.5 * cos(3.0*u/2.0) /3
594
+ sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,4*pi), (v,0,2*pi), frame=False, color='red', opacity=0.7))
595
+
596
+ Steiner surface/Roman's surface (see
597
+ :wikipedia:`Roman_surface` and
598
+ :wikipedia:`Steiner_surface`)::
599
+
600
+ sage: u, v = var('u,v')
601
+ sage: f_x = (sin(2*u) * cos(v) * cos(v))
602
+ sage: f_y = (sin(u) * sin(2*v))
603
+ sage: f_z = (cos(u) * sin(2*v))
604
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,-pi/2,pi/2), (v,-pi/2,pi/2), frame=False, color='red')
605
+ Graphics3d Object
606
+
607
+ .. PLOT::
608
+
609
+ u, v = var('u,v')
610
+ f_x = (sin(2*u) * cos(v) * cos(v))
611
+ f_y = (sin(u) * sin(2*v))
612
+ f_z = (cos(u) * sin(2*v))
613
+ sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-pi/2,pi/2), (v,-pi/2,pi/2), frame=False, color='red'))
614
+
615
+ Klein bottle? (see :wikipedia:`Klein_bottle`)::
616
+
617
+ sage: u, v = var('u,v')
618
+ sage: f_x = (3*(1+sin(v)) + 2*(1-cos(v)/2)*cos(u)) * cos(v)
619
+ sage: f_y = (4+2*(1-cos(v)/2)*cos(u)) * sin(v)
620
+ sage: f_z = -2 * (1-cos(v)/2) * sin(u)
621
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color='green')
622
+ Graphics3d Object
623
+
624
+ .. PLOT::
625
+
626
+ u, v = var('u,v')
627
+ f_x = (3*(1+sin(v)) + 2*(1-cos(v)/2)*cos(u)) * cos(v)
628
+ f_y = (4+2*(1-cos(v)/2)*cos(u)) * sin(v)
629
+ f_z = -2 * (1-cos(v)/2) * sin(u)
630
+ sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color='green'))
631
+
632
+ A Figure 8 embedding of the Klein bottle (see
633
+ :wikipedia:`Klein_bottle`)::
634
+
635
+ sage: u, v = var('u,v')
636
+ sage: f_x = (2+cos(v/2)*sin(u)-sin(v/2)*sin(2*u)) * cos(v)
637
+ sage: f_y = (2+cos(v/2)*sin(u)-sin(v/2)*sin(2*u)) * sin(v)
638
+ sage: f_z = sin(v/2)*sin(u) + cos(v/2)*sin(2*u)
639
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color='red')
640
+ Graphics3d Object
641
+
642
+ .. PLOT::
643
+
644
+ u, v = var('u,v')
645
+ f_x = (2+cos(0.5*v)*sin(u)-sin(0.5*v)*sin(2*u)) * cos(v)
646
+ f_y = (2+cos(0.5*v)*sin(u)-sin(0.5*v)*sin(2*u)) * sin(v)
647
+ f_z = sin(v*0.5)*sin(u) + cos(v*0.5)*sin(2*u)
648
+ sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0,2*pi), frame=False, color='red'))
649
+
650
+ Enneper's surface (see
651
+ :wikipedia:`Enneper_surface`)::
652
+
653
+ sage: u, v = var('u,v')
654
+ sage: f_x = u - u^3/3 + u*v^2
655
+ sage: f_y = v - v^3/3 + v*u^2
656
+ sage: f_z = u^2 - v^2
657
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,-2,2), (v,-2,2), frame=False, color='red')
658
+ Graphics3d Object
659
+
660
+ .. PLOT::
661
+
662
+ u, v = var('u,v')
663
+ f_x = u - u**3/3 + u*v**2
664
+ f_y = v - v**3/3 + v*u**2
665
+ f_z = u**2 - v**2
666
+ sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-2,2), (v,-2,2), frame=False, color='red'))
667
+
668
+ Henneberg's surface
669
+ (see http://xahlee.org/surface/gallery_m.html)::
670
+
671
+ sage: u, v = var('u,v')
672
+ sage: f_x = 2*sinh(u)*cos(v) - (2/3)*sinh(3*u)*cos(3*v)
673
+ sage: f_y = 2*sinh(u)*sin(v) + (2/3)*sinh(3*u)*sin(3*v)
674
+ sage: f_z = 2 * cosh(2*u) * cos(2*v)
675
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,-1,1), (v,-pi/2,pi/2), frame=False, color='red')
676
+ Graphics3d Object
677
+
678
+ .. PLOT::
679
+
680
+ u, v = var('u,v')
681
+ f_x = 2.0*sinh(u)*cos(v) - (2.0/3.0)*sinh(3*u)*cos(3*v)
682
+ f_y = 2.0*sinh(u)*sin(v) + (2.0/3.0)*sinh(3*u)*sin(3*v)
683
+ f_z = 2.0 * cosh(2*u) * cos(2*v)
684
+ sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-1,1), (v,-pi/2,pi/2), frame=False, color='red'))
685
+
686
+ Dini's spiral::
687
+
688
+ sage: u, v = var('u,v')
689
+ sage: f_x = cos(u) * sin(v)
690
+ sage: f_y = sin(u) * sin(v)
691
+ sage: f_z = (cos(v)+log(tan(v/2))) + 0.2*u
692
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,0,12.4), (v,0.1,2), frame=False, color='red')
693
+ Graphics3d Object
694
+
695
+ .. PLOT::
696
+
697
+ u, v = var('u,v')
698
+ f_x = cos(u) * sin(v)
699
+ f_y = sin(u) * sin(v)
700
+ f_z = (cos(v)+log(tan(v*0.5))) + 0.2*u
701
+ sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,12.4), (v,0.1,2), frame=False, color='red'))
702
+
703
+ Catalan's surface (see
704
+ http://xahlee.org/surface/catalan/catalan.html)::
705
+
706
+ sage: u, v = var('u,v')
707
+ sage: f_x = u - sin(u)*cosh(v)
708
+ sage: f_y = 1 - cos(u)*cosh(v)
709
+ sage: f_z = 4 * sin(1/2*u) * sinh(v/2)
710
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,-pi,3*pi), (v,-2,2), frame=False, color='red')
711
+ Graphics3d Object
712
+
713
+ .. PLOT::
714
+
715
+ u, v = var('u,v')
716
+ f_x = u - sin(u)*cosh(v)
717
+ f_y = 1.0 - cos(u)*cosh(v)
718
+ f_z = 4.0 * sin(0.5*u) * sinh(0.5*v)
719
+ sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-pi,3*pi), (v,-2,2), frame=False, color='red'))
720
+
721
+ A Conchoid::
722
+
723
+ sage: u, v = var('u,v')
724
+ sage: k = 1.2; k_2 = 1.2; a = 1.5
725
+ sage: f = (k^u*(1+cos(v))*cos(u), k^u*(1+cos(v))*sin(u), k^u*sin(v)-a*k_2^u)
726
+ sage: parametric_plot3d(f, (u,0,6*pi), (v,0,2*pi), plot_points=[40,40], texture=(0,0.5,0))
727
+ Graphics3d Object
728
+
729
+ .. PLOT::
730
+
731
+ u, v = var('u,v')
732
+ k = 1.2; k_2 = 1.2; a = 1.5
733
+ f = (k**u*(1+cos(v))*cos(u), k**u*(1+cos(v))*sin(u), k**u*sin(v)-a*k_2**u)
734
+ sphinx_plot(parametric_plot3d(f, (u,0,6*pi), (v,0,2*pi), plot_points=[40,40], texture=(0,0.5,0)))
735
+
736
+ A Möbius strip::
737
+
738
+ sage: u,v = var("u,v")
739
+ sage: parametric_plot3d([cos(u)*(1+v*cos(u/2)), sin(u)*(1+v*cos(u/2)), 0.2*v*sin(u/2)],
740
+ ....: (u,0, 4*pi+0.5), (v,0, 0.3), plot_points=[50,50])
741
+ Graphics3d Object
742
+
743
+ .. PLOT::
744
+
745
+ u,v = var("u,v")
746
+ sphinx_plot(parametric_plot3d([cos(u)*(1+v*cos(u*0.5)), sin(u)*(1+v*cos(u*0.5)), 0.2*v*sin(u*0.5)],
747
+ (u,0,4*pi+0.5), (v,0,0.3), plot_points=[50,50]))
748
+
749
+ A Twisted Ribbon::
750
+
751
+ sage: u, v = var('u,v')
752
+ sage: parametric_plot3d([3*sin(u)*cos(v), 3*sin(u)*sin(v), cos(v)],
753
+ ....: (u,0,2*pi), (v,0,pi), plot_points=[50,50])
754
+ Graphics3d Object
755
+
756
+ .. PLOT::
757
+
758
+ u, v = var('u,v')
759
+ sphinx_plot(parametric_plot3d([3*sin(u)*cos(v), 3*sin(u)*sin(v), cos(v)],
760
+ (u,0,2*pi), (v,0,pi), plot_points=[50,50]))
761
+
762
+ An Ellipsoid::
763
+
764
+ sage: u, v = var('u,v')
765
+ sage: parametric_plot3d([3*sin(u)*cos(v), 2*sin(u)*sin(v), cos(u)],
766
+ ....: (u,0, 2*pi), (v, 0, 2*pi), plot_points=[50,50], aspect_ratio=[1,1,1])
767
+ Graphics3d Object
768
+
769
+ .. PLOT::
770
+
771
+ u, v = var('u,v')
772
+ sphinx_plot(parametric_plot3d([3*sin(u)*cos(v), 2*sin(u)*sin(v), cos(u)],
773
+ (u,0,2*pi), (v,0,2*pi), plot_points=[50,50], aspect_ratio=[1,1,1]))
774
+
775
+ A Cone::
776
+
777
+ sage: u, v = var('u,v')
778
+ sage: parametric_plot3d([u*cos(v), u*sin(v), u], (u,-1,1), (v,0,2*pi+0.5), plot_points=[50,50])
779
+ Graphics3d Object
780
+
781
+ .. PLOT::
782
+
783
+ u, v = var('u,v')
784
+ sphinx_plot(parametric_plot3d([u*cos(v), u*sin(v), u], (u,-1,1), (v,0,2*pi+0.5), plot_points=[50,50]))
785
+
786
+ A Paraboloid::
787
+
788
+ sage: u, v = var('u,v')
789
+ sage: parametric_plot3d([u*cos(v), u*sin(v), u^2], (u,0,1), (v,0,2*pi+0.4), plot_points=[50,50])
790
+ Graphics3d Object
791
+
792
+ .. PLOT::
793
+
794
+ u, v = var('u,v')
795
+ sphinx_plot(parametric_plot3d([u*cos(v), u*sin(v), u**2], (u,0,1), (v,0,2*pi+0.4), plot_points=[50,50]))
796
+
797
+ A Hyperboloid::
798
+
799
+ sage: u, v = var('u,v')
800
+ sage: plot3d(u^2-v^2, (u,-1,1), (v,-1,1), plot_points=[50,50])
801
+ Graphics3d Object
802
+
803
+ .. PLOT::
804
+
805
+ u, v = var('u,v')
806
+ sphinx_plot(plot3d(u**2-v**2, (u,-1,1), (v,-1,1), plot_points=[50,50]))
807
+
808
+ A weird looking surface - like a Möbius band but also an O::
809
+
810
+ sage: u, v = var('u,v')
811
+ sage: parametric_plot3d([sin(u)*cos(u)*log(u^2)*sin(v), (u^2)^(1/6)*(cos(u)^2)^(1/4)*cos(v), sin(v)],
812
+ ....: (u,0.001,1), (v,-pi,pi+0.2), plot_points=[50,50])
813
+ Graphics3d Object
814
+
815
+ .. PLOT::
816
+
817
+ u, v = var('u,v')
818
+ sphinx_plot(parametric_plot3d([sin(u)*cos(u)*log(u**2)*sin(v), (u**2)**(1.0/6.0)*(cos(u)**2)**(0.25)*cos(v), sin(v)],
819
+ (u,0.001,1),
820
+ (v,-pi,pi+0.2),
821
+ plot_points=[50,50]))
822
+
823
+ A heart, but not a cardioid (for my wife)::
824
+
825
+ sage: u, v = var('u,v')
826
+ sage: p1 = parametric_plot3d([sin(u)*cos(u)*log(u^2)*v*(1-v)/2, ((u^6)^(1/20)*(cos(u)^2)^(1/4)-1/2)*v*(1-v), v^(0.5)],
827
+ ....: (u,0.001,1), (v,0,1), plot_points=[70,70], color='red')
828
+ sage: p2 = parametric_plot3d([-sin(u)*cos(u)*log(u^2)*v*(1-v)/2, ((u^6)^(1/20)*(cos(u)^2)^(1/4)-1/2)*v*(1-v), v^(0.5)],
829
+ ....: (u, 0.001,1), (v,0,1), plot_points=[70,70], color='red')
830
+ sage: show(p1+p2)
831
+
832
+ .. PLOT::
833
+
834
+ u, v = var('u,v')
835
+ p1 = parametric_plot3d([sin(u)*cos(u)*log(u**2)*v*(1-v)*0.5, ((u**6)**(1/20.0)*(cos(u)**2)**(0.25)-0.5)*v*(1-v), v**(0.5)],
836
+ (u,0.001,1), (v,0,1), plot_points=[70,70], color='red')
837
+ p2 = parametric_plot3d([-sin(u)*cos(u)*log(u**2)*v*(1-v)*0.5, ((u**6)**(1/20.0)*(cos(u)**2)**(0.25)-0.5)*v*(1-v), v**(0.5)],
838
+ (u,0.001,1), (v,0,1), plot_points=[70,70], color='red')
839
+ sphinx_plot(p1+p2)
840
+
841
+ A Hyperhelicoidal::
842
+
843
+ sage: u = var("u")
844
+ sage: v = var("v")
845
+ sage: f_x = (sinh(v)*cos(3*u)) / (1+cosh(u)*cosh(v))
846
+ sage: f_y = (sinh(v)*sin(3*u)) / (1+cosh(u)*cosh(v))
847
+ sage: f_z = (cosh(v)*sinh(u)) / (1+cosh(u)*cosh(v))
848
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-pi,pi), plot_points=[50,50], frame=False, color='red')
849
+ Graphics3d Object
850
+
851
+ .. PLOT::
852
+
853
+ u = var("u")
854
+ v = var("v")
855
+ f_x = (sinh(v)*cos(3*u)) / (1+cosh(u)*cosh(v))
856
+ f_y = (sinh(v)*sin(3*u)) / (1+cosh(u)*cosh(v))
857
+ f_z = (cosh(v)*sinh(u)) / (1+cosh(u)*cosh(v))
858
+ sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-pi,pi), plot_points=[50,50], frame=False, color='red'))
859
+
860
+ A Helicoid (lines through a helix,
861
+ :wikipedia:`Helix`)::
862
+
863
+ sage: u, v = var('u,v')
864
+ sage: f_x = sinh(v) * sin(u)
865
+ sage: f_y = -sinh(v) * cos(u)
866
+ sage: f_z = 3 * u
867
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-pi,pi), plot_points=[50,50], frame=False, color='red')
868
+ Graphics3d Object
869
+
870
+ .. PLOT::
871
+
872
+ u, v = var('u,v')
873
+ f_x = sinh(v) * sin(u)
874
+ f_y = -sinh(v) * cos(u)
875
+ f_z = 3 * u
876
+ sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-pi,pi), (v,-pi,pi), plot_points=[50,50], frame=False, color='red'))
877
+
878
+ Kuen's surface
879
+ (http://virtualmathmuseum.org/Surface/kuen/kuen.html)::
880
+
881
+ sage: f_x = (2*(cos(u) + u*sin(u))*sin(v))/(1+ u^2*sin(v)^2)
882
+ sage: f_y = (2*(sin(u) - u*cos(u))*sin(v))/(1+ u^2*sin(v)^2)
883
+ sage: f_z = log(tan(1/2 *v)) + (2*cos(v))/(1+ u^2*sin(v)^2)
884
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0.01,pi-0.01), plot_points=[50,50], frame=False, color='green')
885
+ Graphics3d Object
886
+
887
+ .. PLOT::
888
+
889
+ u, v = var('u,v')
890
+ f_x = (2.0*(cos(u)+u*sin(u))*sin(v)) / (1.0+u**2*sin(v)**2)
891
+ f_y = (2.0*(sin(u)-u*cos(u))*sin(v)) / (1.0+u**2*sin(v)**2)
892
+ f_z = log(tan(0.5 *v)) + (2*cos(v))/(1.0+u**2*sin(v)**2)
893
+ sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,0,2*pi), (v,0.01,pi-0.01), plot_points=[50,50], frame=False, color='green'))
894
+
895
+ A 5-pointed star::
896
+
897
+ sage: G1 = (abs(cos(u/4))^0.5+abs(sin(u/4))^0.5)^(-1/0.3)
898
+ sage: G2 = (abs(cos(5*v/4))^1.7+abs(sin(5*v/4))^1.7)^(-1/0.1)
899
+ sage: f_x = cos(u) * cos(v) * G1 * G2
900
+ sage: f_y = cos(u) * sin(v) * G1 * G2
901
+ sage: f_z = sin(u) * G1
902
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,-pi/2,pi/2), (v,0,2*pi), plot_points=[50,50], frame=False, color='green')
903
+ Graphics3d Object
904
+
905
+ .. PLOT::
906
+
907
+ u, v = var('u,v')
908
+ G1 = (abs(cos(u/4))**0.5+abs(sin(u/4))**0.5)**(-1/0.3)
909
+ G2 = (abs(cos(5*v/4))**1.7+abs(sin(5*v/4))**1.7)**(-1/0.1)
910
+ f_x = cos(u) * cos(v) * G1 * G2
911
+ f_y = cos(u) * sin(v) * G1 * G2
912
+ f_z = sin(u) * G1
913
+ sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-pi/2,pi/2), (v,0,2*pi), plot_points=[50,50], frame=False, color='green'))
914
+
915
+ A cool self-intersecting surface (Eppener surface?)::
916
+
917
+ sage: f_x = u - u^3/3 + u*v^2
918
+ sage: f_y = v - v^3/3 + v*u^2
919
+ sage: f_z = u^2 - v^2
920
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,-25,25), (v,-25,25), plot_points=[50,50], frame=False, color='green')
921
+ Graphics3d Object
922
+
923
+ .. PLOT::
924
+
925
+ u, v = var('u,v')
926
+ f_x = u - u**3/3 + u*v**2
927
+ f_y = v - v**3/3 + v*u**2
928
+ f_z = u**2 - v**2
929
+ sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-25,25), (v,-25,25), plot_points=[50,50], frame=False, color='green'))
930
+
931
+ The breather surface
932
+ (:wikipedia:`Breather_surface`)::
933
+
934
+ sage: K = sqrt(0.84)
935
+ sage: G = (0.4*((K*cosh(0.4*u))^2 + (0.4*sin(K*v))^2))
936
+ sage: f_x = (2*K*cosh(0.4*u)*(-(K*cos(v)*cos(K*v)) - sin(v)*sin(K*v)))/G
937
+ sage: f_y = (2*K*cosh(0.4*u)*(-(K*sin(v)*cos(K*v)) + cos(v)*sin(K*v)))/G
938
+ sage: f_z = -u + (2*0.84*cosh(0.4*u)*sinh(0.4*u))/G
939
+ sage: parametric_plot3d([f_x, f_y, f_z], (u,-13.2,13.2), (v,-37.4,37.4), plot_points=[90,90], frame=False, color='green')
940
+ Graphics3d Object
941
+
942
+ .. PLOT::
943
+
944
+ u, v = var('u,v')
945
+ K = sqrt(0.84)
946
+ G = (0.4*((K*cosh(0.4*u))**2 + (0.4*sin(K*v))**2))
947
+ f_x = (2*K*cosh(0.4*u)*(-(K*cos(v)*cos(K*v)) - sin(v)*sin(K*v)))/G
948
+ f_y = (2*K*cosh(0.4*u)*(-(K*sin(v)*cos(K*v)) + cos(v)*sin(K*v)))/G
949
+ f_z = -u + (2*0.84*cosh(0.4*u)*sinh(0.4*u))/G
950
+ sphinx_plot(parametric_plot3d([f_x, f_y, f_z], (u,-13.2,13.2), (v,-37.4,37.4), plot_points=[90,90], frame=False, color='green'))
951
+
952
+ TESTS::
953
+
954
+ sage: u, v = var('u,v')
955
+ sage: plot3d(u^2-v^2, (u,-1,1), (u,-1,1))
956
+ Traceback (most recent call last):
957
+ ...
958
+ ValueError: range variables should be distinct, but there are duplicates
959
+
960
+
961
+ From :issue:`2858`::
962
+
963
+ sage: parametric_plot3d((u,-u,v), (u,-10,10),(v,-10,10))
964
+ Graphics3d Object
965
+ sage: f(u)=u; g(v)=v^2; parametric_plot3d((g,f,f), (-10,10),(-10,10))
966
+ Graphics3d Object
967
+
968
+ From :issue:`5368`::
969
+
970
+ sage: x, y = var('x,y')
971
+ sage: plot3d(x*y^2 - sin(x), (x,-1,1), (y,-1,1))
972
+ Graphics3d Object
973
+ """
974
+ # TODO:
975
+ # * Surface -- behavior of functions not defined everywhere -- see note above
976
+ # * Iterative refinement
977
+
978
+ # color_function -- (default: ``'automatic'``) how to determine the color of curves and surfaces
979
+ # color_function_scaling -- boolean (default: ``True``); whether to scale the input to color_function
980
+ # exclusions -- (default: ``'automatic'``) u points or (u,v) conditions to exclude.
981
+ # (E.g., exclusions could be a function e = lambda u, v: False if u < v else True
982
+ # exclusions_style -- (default: ``None``) what to draw at excluded points
983
+ # max_recursion -- (default: ``'automatic'``) maximum number of recursive subdivisions,
984
+ # when ...
985
+ # mesh -- (default: ``'automatic'``) how many mesh divisions in each direction to draw
986
+ # mesh_functions -- (default: ``'automatic'``) how to determine the placement of mesh divisions
987
+ # mesh_shading -- (default: ``None``) how to shade regions between mesh divisions
988
+ # plot_range -- (default: ``'automatic'``) range of values to include
989
+
990
+ if isinstance(f, Vector):
991
+ f = tuple(f)
992
+
993
+ if isinstance(f, (list, tuple)) and f and isinstance(f[0], (list, tuple)):
994
+ return sum(parametric_plot3d(v, urange, vrange, plot_points=plot_points, **kwds) for v in f)
995
+
996
+ if not isinstance(f, (tuple, list)) or len(f) != 3:
997
+ raise ValueError("f must be a list, tuple, or vector of length 3")
998
+
999
+ if vrange is None:
1000
+ if plot_points == "automatic":
1001
+ plot_points = 75
1002
+ G = _parametric_plot3d_curve(f, urange, plot_points=plot_points, **kwds)
1003
+ else:
1004
+ if plot_points == "automatic":
1005
+ plot_points = [40, 40]
1006
+ G = _parametric_plot3d_surface(f, urange, vrange, plot_points=plot_points, boundary_style=boundary_style, **kwds)
1007
+ G._set_extra_kwds(kwds)
1008
+ return G
1009
+
1010
+
1011
+ def _parametric_plot3d_curve(f, urange, plot_points, **kwds):
1012
+ r"""
1013
+ Return a parametric three-dimensional space curve.
1014
+ This function is used internally by the
1015
+ :func:`parametric_plot3d` command.
1016
+
1017
+ There are two ways this function is invoked by
1018
+ :func:`parametric_plot3d`.
1019
+
1020
+ - ``parametric_plot3d([f_x, f_y, f_z], (u_min,
1021
+ u_max))``:
1022
+ `f_x, f_y, f_z` are three functions and
1023
+ `u_{\min}` and `u_{\max}` are real numbers
1024
+
1025
+ - ``parametric_plot3d([f_x, f_y, f_z], (u, u_min,
1026
+ u_max))``:
1027
+ `f_x, f_y, f_z` can be viewed as functions of
1028
+ `u`
1029
+
1030
+ INPUT:
1031
+
1032
+ - ``f`` -- a 3-tuple of functions or expressions, or vector of size 3
1033
+
1034
+ - ``urange`` -- a 2-tuple (u_min, u_max) or a 3-tuple
1035
+ (u, u_min, u_max)
1036
+
1037
+ - ``plot_points`` -- integer (default: 75, "automatic"); initial
1038
+ number of sample points in each parameter
1039
+
1040
+ EXAMPLES:
1041
+
1042
+ We demonstrate each of the two ways of calling this. See
1043
+ :func:`parametric_plot3d` for many more examples.
1044
+
1045
+ We do the first one with a lambda function, which creates a
1046
+ callable Python function that sends `u` to `u/10`::
1047
+
1048
+ sage: parametric_plot3d((sin, cos, lambda u: u/10), (0,20)) # indirect doctest
1049
+ Graphics3d Object
1050
+
1051
+ Now we do the same thing with symbolic expressions::
1052
+
1053
+ sage: u = var('u')
1054
+ sage: parametric_plot3d((sin(u), cos(u), u/10), (u,0,20))
1055
+ Graphics3d Object
1056
+ """
1057
+ from sage.plot.misc import setup_for_eval_on_grid
1058
+ g, ranges = setup_for_eval_on_grid(f, [urange], plot_points)
1059
+ f_x, f_y, f_z = g
1060
+ w = [(f_x(u), f_y(u), f_z(u)) for u in xsrange(*ranges[0], include_endpoint=True)]
1061
+ return line3d(w, **kwds)
1062
+
1063
+
1064
+ def _parametric_plot3d_surface(f, urange, vrange, plot_points, boundary_style, **kwds):
1065
+ r"""
1066
+ Return a parametric three-dimensional space surface.
1067
+ This function is used internally by the
1068
+ :func:`parametric_plot3d` command.
1069
+
1070
+ There are two ways this function is invoked by
1071
+ :func:`parametric_plot3d`.
1072
+
1073
+ - ``parametric_plot3d([f_x, f_y, f_z], (u_min, u_max),
1074
+ (v_min, v_max))``:
1075
+ `f_x, f_y, f_z` are each functions of two variables
1076
+
1077
+ - ``parametric_plot3d([f_x, f_y, f_z], (u, u_min,
1078
+ u_max), (v, v_min, v_max))``:
1079
+ `f_x, f_y, f_z` can be viewed as functions of
1080
+ `u` and `v`
1081
+
1082
+ INPUT:
1083
+
1084
+ - ``f`` -- a 3-tuple of functions or expressions, or vector of size 3
1085
+
1086
+ - ``urange`` -- a 2-tuple (u_min, u_max) or a 3-tuple
1087
+ (u, u_min, u_max)
1088
+
1089
+ - ``vrange`` -- a 2-tuple (v_min, v_max) or a 3-tuple
1090
+ (v, v_min, v_max)
1091
+
1092
+ - ``plot_points`` -- (default: "automatic", which is [40,40]
1093
+ for surfaces) initial number of sample points in each parameter;
1094
+ a pair of integers.
1095
+
1096
+ - ``boundary_style`` -- (default: None, no boundary) a dict that describes
1097
+ how to draw the boundaries of regions by giving options that are passed
1098
+ to the line3d command.
1099
+
1100
+ EXAMPLES:
1101
+
1102
+ We demonstrate each of the two ways of calling this. See
1103
+ :func:`parametric_plot3d` for many more examples.
1104
+
1105
+ We do the first one with lambda functions::
1106
+
1107
+ sage: f = (lambda u,v: cos(u), lambda u,v: sin(u)+cos(v), lambda u,v: sin(v))
1108
+ sage: parametric_plot3d(f, (0, 2*pi), (-pi, pi)) # indirect doctest
1109
+ Graphics3d Object
1110
+
1111
+ Now we do the same thing with symbolic expressions::
1112
+
1113
+ sage: u, v = var('u,v')
1114
+ sage: parametric_plot3d((cos(u), sin(u) + cos(v), sin(v)), (u, 0, 2*pi), (v, -pi, pi), mesh=True)
1115
+ Graphics3d Object
1116
+ """
1117
+ from sage.plot.misc import setup_for_eval_on_grid
1118
+ g, ranges = setup_for_eval_on_grid(f, [urange, vrange], plot_points)
1119
+ urange = srange(*ranges[0], include_endpoint=True)
1120
+ vrange = srange(*ranges[1], include_endpoint=True)
1121
+ G = ParametricSurface(g, (urange, vrange), **kwds)
1122
+
1123
+ if boundary_style is not None:
1124
+ for u in (urange[0], urange[-1]):
1125
+ G += line3d([(g[0](u, v), g[1](u, v), g[2](u, v)) for v in vrange],
1126
+ **boundary_style)
1127
+ for v in (vrange[0], vrange[-1]):
1128
+ G += line3d([(g[0](u, v), g[1](u, v), g[2](u, v)) for u in urange],
1129
+ **boundary_style)
1130
+ return G