passagemath-plot 10.6.31rc3__cp314-cp314-macosx_13_0_arm64.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 (82) hide show
  1. passagemath_plot-10.6.31rc3.dist-info/METADATA +172 -0
  2. passagemath_plot-10.6.31rc3.dist-info/RECORD +82 -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.dylibs/libgfortran.5.dylib +0 -0
  6. passagemath_plot.dylibs/libgsl.28.dylib +0 -0
  7. passagemath_plot.dylibs/libopenblasp-r0.3.29.dylib +0 -0
  8. passagemath_plot.dylibs/libquadmath.0.dylib +0 -0
  9. sage/all__sagemath_plot.py +15 -0
  10. sage/ext_data/threejs/animation.css +195 -0
  11. sage/ext_data/threejs/animation.html +85 -0
  12. sage/ext_data/threejs/animation.js +273 -0
  13. sage/ext_data/threejs/fat_lines.js +48 -0
  14. sage/ext_data/threejs/threejs-version.txt +1 -0
  15. sage/ext_data/threejs/threejs_template.html +597 -0
  16. sage/interfaces/all__sagemath_plot.py +1 -0
  17. sage/interfaces/gnuplot.py +196 -0
  18. sage/interfaces/jmoldata.py +208 -0
  19. sage/interfaces/povray.py +56 -0
  20. sage/plot/all.py +42 -0
  21. sage/plot/animate.py +1796 -0
  22. sage/plot/arc.py +504 -0
  23. sage/plot/arrow.py +671 -0
  24. sage/plot/bar_chart.py +205 -0
  25. sage/plot/bezier_path.py +400 -0
  26. sage/plot/circle.py +435 -0
  27. sage/plot/colors.py +1606 -0
  28. sage/plot/complex_plot.cpython-314-darwin.so +0 -0
  29. sage/plot/complex_plot.pyx +1446 -0
  30. sage/plot/contour_plot.py +1792 -0
  31. sage/plot/density_plot.py +318 -0
  32. sage/plot/disk.py +373 -0
  33. sage/plot/ellipse.py +375 -0
  34. sage/plot/graphics.py +3580 -0
  35. sage/plot/histogram.py +354 -0
  36. sage/plot/hyperbolic_arc.py +404 -0
  37. sage/plot/hyperbolic_polygon.py +416 -0
  38. sage/plot/hyperbolic_regular_polygon.py +296 -0
  39. sage/plot/line.py +626 -0
  40. sage/plot/matrix_plot.py +629 -0
  41. sage/plot/misc.py +509 -0
  42. sage/plot/multigraphics.py +1294 -0
  43. sage/plot/plot.py +4183 -0
  44. sage/plot/plot3d/all.py +23 -0
  45. sage/plot/plot3d/base.cpython-314-darwin.so +0 -0
  46. sage/plot/plot3d/base.pxd +12 -0
  47. sage/plot/plot3d/base.pyx +3378 -0
  48. sage/plot/plot3d/implicit_plot3d.py +659 -0
  49. sage/plot/plot3d/implicit_surface.cpython-314-darwin.so +0 -0
  50. sage/plot/plot3d/implicit_surface.pyx +1453 -0
  51. sage/plot/plot3d/index_face_set.cpython-314-darwin.so +0 -0
  52. sage/plot/plot3d/index_face_set.pxd +32 -0
  53. sage/plot/plot3d/index_face_set.pyx +1873 -0
  54. sage/plot/plot3d/introduction.py +131 -0
  55. sage/plot/plot3d/list_plot3d.py +649 -0
  56. sage/plot/plot3d/parametric_plot3d.py +1130 -0
  57. sage/plot/plot3d/parametric_surface.cpython-314-darwin.so +0 -0
  58. sage/plot/plot3d/parametric_surface.pxd +12 -0
  59. sage/plot/plot3d/parametric_surface.pyx +893 -0
  60. sage/plot/plot3d/platonic.py +601 -0
  61. sage/plot/plot3d/plot3d.py +1442 -0
  62. sage/plot/plot3d/plot_field3d.py +162 -0
  63. sage/plot/plot3d/point_c.pxi +148 -0
  64. sage/plot/plot3d/revolution_plot3d.py +309 -0
  65. sage/plot/plot3d/shapes.cpython-314-darwin.so +0 -0
  66. sage/plot/plot3d/shapes.pxd +22 -0
  67. sage/plot/plot3d/shapes.pyx +1382 -0
  68. sage/plot/plot3d/shapes2.py +1512 -0
  69. sage/plot/plot3d/tachyon.py +1779 -0
  70. sage/plot/plot3d/texture.py +453 -0
  71. sage/plot/plot3d/transform.cpython-314-darwin.so +0 -0
  72. sage/plot/plot3d/transform.pxd +21 -0
  73. sage/plot/plot3d/transform.pyx +268 -0
  74. sage/plot/plot3d/tri_plot.py +589 -0
  75. sage/plot/plot_field.py +362 -0
  76. sage/plot/point.py +624 -0
  77. sage/plot/polygon.py +562 -0
  78. sage/plot/primitive.py +249 -0
  79. sage/plot/scatter_plot.py +199 -0
  80. sage/plot/step.py +85 -0
  81. sage/plot/streamline_plot.py +328 -0
  82. sage/plot/text.py +432 -0
@@ -0,0 +1,162 @@
1
+ # sage_setup: distribution = sagemath-plot
2
+ # sage.doctest: needs sage.symbolic
3
+ """
4
+ Plotting 3D fields
5
+ """
6
+ # ****************************************************************************
7
+ # Copyright (C) 2009 Jason Grout <jason-sage@creativetrax.com>
8
+ #
9
+ # Distributed under the terms of the GNU General Public License (GPL)
10
+ #
11
+ # This code is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ # General Public License for more details.
15
+ #
16
+ # The full text of the GPL is available at:
17
+ #
18
+ # https://www.gnu.org/licenses/
19
+ # ****************************************************************************
20
+
21
+ from sage.arith.srange import srange
22
+ from sage.plot.misc import setup_for_eval_on_grid
23
+ from sage.modules.free_module_element import vector
24
+ from sage.plot.plot import plot
25
+
26
+
27
+ def plot_vector_field3d(functions, xrange, yrange, zrange,
28
+ plot_points=5, colors='jet', center_arrows=False, **kwds):
29
+ r"""
30
+ Plot a 3d vector field.
31
+
32
+ INPUT:
33
+
34
+ - ``functions`` -- list of three functions, representing the x-,
35
+ y-, and z-coordinates of a vector
36
+
37
+ - ``xrange``, ``yrange``, and ``zrange`` -- three tuples of the
38
+ form (var, start, stop), giving the variables and ranges for each axis
39
+
40
+ - ``plot_points`` -- (default: 5) either a number or list of three
41
+ numbers, specifying how many points to plot for each axis
42
+
43
+ - ``colors`` -- (default: ``'jet'``) a color, list of colors (which are
44
+ interpolated between), or matplotlib colormap name, giving the coloring
45
+ of the arrows. If a list of colors or a colormap is given,
46
+ coloring is done as a function of length of the vector
47
+
48
+ - ``center_arrows`` -- (default: ``False``) if ``True``, draw the arrows
49
+ centered on the points; otherwise, draw the arrows with the tail
50
+ at the point
51
+
52
+ - any other keywords are passed on to the :func:`plot` command for each arrow
53
+
54
+ EXAMPLES:
55
+
56
+ A 3d vector field::
57
+
58
+ sage: x,y,z = var('x y z')
59
+ sage: plot_vector_field3d((x*cos(z), -y*cos(z), sin(z)),
60
+ ....: (x,0,pi), (y,0,pi), (z,0,pi))
61
+ Graphics3d Object
62
+
63
+ .. PLOT::
64
+
65
+ x,y,z=var('x y z')
66
+ sphinx_plot(plot_vector_field3d((x*cos(z),-y*cos(z),sin(z)), (x,0,pi), (y,0,pi), (z,0,pi)))
67
+
68
+ same example with only a list of colors::
69
+
70
+ sage: plot_vector_field3d((x*cos(z), -y*cos(z), sin(z)),
71
+ ....: (x,0,pi), (y,0,pi), (z,0,pi),
72
+ ....: colors=['red','green','blue'])
73
+ Graphics3d Object
74
+
75
+ .. PLOT::
76
+
77
+ x,y,z=var('x y z')
78
+ sphinx_plot(plot_vector_field3d((x*cos(z),-y*cos(z),sin(z)), (x,0,pi), (y,0,pi), (z,0,pi),colors=['red','green','blue']))
79
+
80
+ same example with only one color::
81
+
82
+ sage: plot_vector_field3d((x*cos(z), -y*cos(z), sin(z)),
83
+ ....: (x,0,pi), (y,0,pi), (z,0,pi), colors='red')
84
+ Graphics3d Object
85
+
86
+ .. PLOT::
87
+
88
+ x,y,z=var('x y z')
89
+ sphinx_plot(plot_vector_field3d((x*cos(z),-y*cos(z),sin(z)), (x,0,pi), (y,0,pi), (z,0,pi),colors='red'))
90
+
91
+ same example with the same plot points for the three axes::
92
+
93
+ sage: plot_vector_field3d((x*cos(z), -y*cos(z), sin(z)),
94
+ ....: (x,0,pi), (y,0,pi), (z,0,pi), plot_points=4)
95
+ Graphics3d Object
96
+
97
+ .. PLOT::
98
+
99
+ x,y,z=var('x y z')
100
+ sphinx_plot(plot_vector_field3d((x*cos(z),-y*cos(z),sin(z)), (x,0,pi), (y,0,pi), (z,0,pi),plot_points=4))
101
+
102
+ same example with different number of plot points for each axis::
103
+
104
+ sage: plot_vector_field3d((x*cos(z), -y*cos(z), sin(z)),
105
+ ....: (x,0,pi), (y,0,pi), (z,0,pi), plot_points=[3,5,7])
106
+ Graphics3d Object
107
+
108
+ .. PLOT::
109
+
110
+ x,y,z=var('x y z')
111
+ sphinx_plot(plot_vector_field3d((x*cos(z),-y*cos(z),sin(z)), (x,0,pi), (y,0,pi), (z,0,pi),plot_points=[3,5,7]))
112
+
113
+ same example with the arrows centered on the points::
114
+
115
+ sage: plot_vector_field3d((x*cos(z), -y*cos(z), sin(z)),
116
+ ....: (x,0,pi), (y,0,pi), (z,0,pi), center_arrows=True)
117
+ Graphics3d Object
118
+
119
+ .. PLOT::
120
+
121
+ x,y,z=var('x y z')
122
+ sphinx_plot(plot_vector_field3d((x*cos(z),-y*cos(z),sin(z)), (x,0,pi), (y,0,pi), (z,0,pi),center_arrows=True))
123
+
124
+
125
+ TESTS:
126
+
127
+ This tests that :issue:`2100` is fixed in a way compatible with this command::
128
+
129
+ sage: plot_vector_field3d((x*cos(z),-y*cos(z),sin(z)), (x,0,pi), (y,0,pi), (z,0,pi),center_arrows=True,aspect_ratio=(1,2,1))
130
+ Graphics3d Object
131
+ """
132
+ (ff, gg, hh), ranges = setup_for_eval_on_grid(functions, [xrange, yrange, zrange], plot_points)
133
+ xpoints, ypoints, zpoints = (srange(*r, include_endpoint=True) for r in ranges)
134
+ points = [vector((i, j, k)) for i in xpoints for j in ypoints for k in zpoints]
135
+ vectors = [vector((ff(*point), gg(*point), hh(*point))) for point in points]
136
+
137
+ try:
138
+ import matplotlib as mpl
139
+ cm = mpl.colormaps[colors]
140
+ except (TypeError, KeyError):
141
+ cm = None
142
+ if cm is None:
143
+ if isinstance(colors, (list, tuple)):
144
+ from matplotlib.colors import LinearSegmentedColormap
145
+ cm = LinearSegmentedColormap.from_list('mymap', colors)
146
+ else:
147
+ def cm(x):
148
+ return colors
149
+
150
+ max_len = max(v.norm() for v in vectors)
151
+ scaled_vectors = [v / max_len for v in vectors]
152
+
153
+ if center_arrows:
154
+ G = sum(plot(v, color=cm(v.norm()), **kwds).translate(p - v / 2)
155
+ for v, p in zip(scaled_vectors, points))
156
+ G._set_extra_kwds(kwds)
157
+ return G
158
+ else:
159
+ G = sum(plot(v, color=cm(v.norm()), **kwds).translate(p)
160
+ for v, p in zip(scaled_vectors, points))
161
+ G._set_extra_kwds(kwds)
162
+ return G
@@ -0,0 +1,148 @@
1
+ # sage_setup: distribution = sagemath-plot
2
+ # ****************************************************************************
3
+ # Copyright (C) 2007 Robert Bradshaw <robertwb@math.washington.edu>
4
+ #
5
+ # Distributed under the terms of the GNU General Public License (GPL)
6
+ #
7
+ # This code is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
+ # General Public License for more details.
11
+ #
12
+ # The full text of the GPL is available at:
13
+ #
14
+ # https://www.gnu.org/licenses/
15
+ # ****************************************************************************
16
+
17
+
18
+ # Utility functions for operating on the point_c struct.
19
+ from libc cimport math
20
+
21
+
22
+ cdef inline bint point_c_set(point_c* res, P) except -2:
23
+ res.x, res.y, res.z = P[0], P[1], P[2]
24
+
25
+ cdef inline bint point_c_eq(point_c P, point_c Q) noexcept:
26
+ return P.x == Q.x and P.y == Q.y and P.z == Q.z
27
+
28
+ cdef inline bint point_c_isfinite(point_c P) noexcept:
29
+ return math.isfinite(P.x) and math.isfinite(P.y) and math.isfinite(P.z)
30
+
31
+ cdef inline int point_c_cmp(point_c P, point_c Q) noexcept:
32
+ """
33
+ Lexographic order
34
+ """
35
+ if P.x == Q.x:
36
+ if P.y == Q.y:
37
+ if P.z == Q.z:
38
+ return 0
39
+ elif P.z < Q.z:
40
+ return -1
41
+ else:
42
+ return 1
43
+ elif P.y < Q.y:
44
+ return -1
45
+ else:
46
+ return 1
47
+ elif P.x < Q.x:
48
+ return -1
49
+ else:
50
+ return 1
51
+
52
+ cdef inline void point_c_update_finite_lower_bound(point_c* res, point_c P) noexcept:
53
+ # We use the condition "not P.x > res.x" so that the condition returns True if res.x is NaN
54
+ if math.isfinite(P.x) and not P.x > res.x:
55
+ res.x = P.x
56
+ if math.isfinite(P.y) and not P.y > res.y:
57
+ res.y = P.y
58
+ if math.isfinite(P.z) and not P.z > res.z:
59
+ res.z = P.z
60
+
61
+ cdef inline void point_c_update_finite_upper_bound(point_c* res, point_c P) noexcept:
62
+ # We use the condition "not P.x < res.x" so that the condition returns True if res.x is NaN
63
+ if math.isfinite(P.x) and not P.x < res.x:
64
+ res.x = P.x
65
+ if math.isfinite(P.y) and not P.y < res.y:
66
+ res.y = P.y
67
+ if math.isfinite(P.z) and not P.z < res.z:
68
+ res.z = P.z
69
+
70
+ cdef inline void point_c_lower_bound(point_c* res, point_c P, point_c Q) noexcept:
71
+ res.x = P.x if P.x < Q.x else Q.x
72
+ res.y = P.y if P.y < Q.y else Q.y
73
+ res.z = P.z if P.z < Q.z else Q.z
74
+
75
+ cdef inline void point_c_upper_bound(point_c* res, point_c P, point_c Q) noexcept:
76
+ res.x = P.x if P.x > Q.x else Q.x
77
+ res.y = P.y if P.y > Q.y else Q.y
78
+ res.z = P.z if P.z > Q.z else Q.z
79
+
80
+ cdef inline void point_c_add(point_c* res, point_c P, point_c Q) noexcept:
81
+ res.x = P.x + Q.x
82
+ res.y = P.y + Q.y
83
+ res.z = P.z + Q.z
84
+
85
+ cdef inline void point_c_sub(point_c* res, point_c P, point_c Q) noexcept:
86
+ res.x = P.x - Q.x
87
+ res.y = P.y - Q.y
88
+ res.z = P.z - Q.z
89
+
90
+ cdef inline void point_c_mul(point_c* res, point_c P, double a) noexcept:
91
+ res.x = a * P.x
92
+ res.y = a * P.y
93
+ res.z = a * P.z
94
+
95
+ cdef inline double point_c_dot(point_c P, point_c Q) noexcept:
96
+ return P.x*Q.x + P.y*Q.y + P.z*Q.z
97
+
98
+ cdef inline void point_c_cross(point_c* res, point_c P, point_c Q) noexcept:
99
+ res.x = P.y * Q.z - P.z * Q.y
100
+ res.y = P.z * Q.x - P.x * Q.z
101
+ res.z = P.x * Q.y - P.y * Q.x
102
+
103
+ cdef inline double point_c_len(point_c P) noexcept:
104
+ return math.sqrt(point_c_dot(P, P))
105
+
106
+ cdef inline void point_c_middle(point_c* res, point_c P, point_c Q, double a) noexcept:
107
+ cdef double b = 1 - a
108
+ res.x = b * P.x + a * Q.x
109
+ res.y = b * P.y + a * Q.y
110
+ res.z = b * P.z + a * Q.z
111
+
112
+ cdef inline void point_c_transform(point_c* res, double* M, point_c P) noexcept:
113
+ """
114
+ M is a flattened 4x4 matrix, row major, representing a Euclidean Transformation.
115
+ Operate on P as a point.
116
+ """
117
+ res.x = M[0]*P.x + M[1]*P.y + M[2]*P.z + M[3]
118
+ res.y = M[4]*P.x + M[5]*P.y + M[6]*P.z + M[7]
119
+ res.z = M[8]*P.x + M[9]*P.y + M[10]*P.z + M[11]
120
+
121
+ cdef inline void point_c_stretch(point_c* res, double* M, point_c P) noexcept:
122
+ """
123
+ M is a flattened 4x4 matrix, row major, representing a Euclidean Transformation.
124
+ Operate on P as a vector (i.e. ignore the translation component)
125
+ """
126
+ res.x = M[0]*P.x + M[1]*P.y + M[2]*P.z
127
+ res.y = M[4]*P.x + M[5]*P.y + M[6]*P.z
128
+ res.z = M[8]*P.x + M[9]*P.y + M[10]*P.z
129
+
130
+ cdef inline void face_c_normal(point_c* res, face_c face, point_c* vlist) noexcept:
131
+ cdef point_c e1, e2
132
+ point_c_sub(&e1, vlist[face.vertices[0]], vlist[face.vertices[1]])
133
+ point_c_sub(&e2, vlist[face.vertices[2]], vlist[face.vertices[1]])
134
+ point_c_cross(res, e1, e2)
135
+
136
+ cdef inline double cos_face_angle(face_c F, face_c E, point_c* vlist) noexcept:
137
+ cdef point_c nF, nE
138
+ face_c_normal(&nF, F, vlist)
139
+ face_c_normal(&nE, E, vlist)
140
+ cdef double dot = point_c_dot(nF, nE)
141
+ return dot / math.sqrt(point_c_dot(nF, nF)*point_c_dot(nE, nE))
142
+
143
+ cdef inline double sin_face_angle(face_c F, face_c E, point_c* vlist) noexcept:
144
+ cdef point_c nF, nE
145
+ face_c_normal(&nF, F, vlist)
146
+ face_c_normal(&nE, E, vlist)
147
+ cdef double dot = point_c_dot(nF, nE)
148
+ return math.sqrt(1-(dot*dot)/(point_c_dot(nF, nF)*point_c_dot(nE, nE)))
@@ -0,0 +1,309 @@
1
+ # sage_setup: distribution = sagemath-plot
2
+ # sage.doctest: needs sage.plot sage.symbolic
3
+ """
4
+ Surfaces of revolution
5
+
6
+ AUTHORS:
7
+
8
+ - Oscar Gerardo Lazo Arjona (2010): initial version.
9
+ """
10
+
11
+ # ****************************************************************************
12
+ # Copyright (C) 2010 Oscar Gerardo Lazo Arjona algebraicamente@gmail.com
13
+ #
14
+ # Distributed under the terms of the GNU General Public License (GPL)
15
+ #
16
+ # This code is distributed in the hope that it will be useful,
17
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ # General Public License for more details.
20
+ #
21
+ # The full text of the GPL is available at:
22
+ #
23
+ # https://www.gnu.org/licenses/
24
+ # ****************************************************************************
25
+ from sage.misc.decorators import rename_keyword
26
+
27
+ from sage.plot.plot3d.parametric_plot3d import parametric_plot3d
28
+
29
+
30
+ @rename_keyword(alpha='opacity')
31
+ def revolution_plot3d(curve, trange, phirange=None, parallel_axis='z', axis=(0, 0), print_vector=False, show_curve=False, **kwds):
32
+ r"""
33
+ Return a plot of a revolved curve.
34
+
35
+ There are three ways to call this function:
36
+
37
+ - ``revolution_plot3d(f,trange)`` where `f` is a function located in the
38
+ `x z` plane.
39
+
40
+ - ``revolution_plot3d((f_x,f_z),trange)`` where `(f_x,f_z)` is a parametric
41
+ curve on the `x z` plane.
42
+
43
+ - ``revolution_plot3d((f_x,f_y,f_z),trange)`` where `(f_x,f_y,f_z)` can be
44
+ any parametric curve.
45
+
46
+ INPUT:
47
+
48
+ - ``curve`` -- a curve to be revolved, specified as a function, a 2-tuple
49
+ or a 3-tuple
50
+
51
+ - ``trange`` -- a 3-tuple `(t,t_{\min},t_{\max})` where t is the
52
+ independent variable of the curve
53
+
54
+ - ``phirange`` -- a 2-tuple of the form `(\phi_{\min},\phi_{\max})`
55
+ (default: `(0,\pi)`) that specifies the angle in which the curve is to be
56
+ revolved
57
+
58
+ - ``parallel_axis`` -- string (one of ``'x'``, ``'y'``, ``'z'``) that
59
+ specifies the coordinate axis parallel to the revolution axis
60
+
61
+ - ``axis`` -- a 2-tuple that specifies the position of the revolution axis.
62
+ If ``parallel_axis`` is:
63
+
64
+ - ``'z'`` -- then ``axis`` is the point in which the revolution axis
65
+ intersects the `x` `y` plane
66
+
67
+ - ``'x'`` -- then ``axis`` is the point in which the revolution axis
68
+ intersects the `y` `z` plane
69
+
70
+ - ``'y'`` -- then ``axis`` is the point in which the revolution axis
71
+ intersects the `x` `z` plane
72
+
73
+ - ``print_vector`` -- if ``True``, the parametrization of the surface of
74
+ revolution will be printed
75
+
76
+ - ``show_curve`` -- if ``True``, the curve will be displayed
77
+
78
+ EXAMPLES:
79
+
80
+ Let's revolve a simple function around different axes::
81
+
82
+ sage: u = var('u')
83
+ sage: f = u^2
84
+ sage: revolution_plot3d(f, (u,0,2),
85
+ ....: show_curve=True, opacity=0.7).show(aspect_ratio=(1,1,1))
86
+
87
+ .. PLOT::
88
+
89
+ u = var('u')
90
+ f = u**2
91
+ P = revolution_plot3d(f, (u,0,2), show_curve=True, opacity=0.7).plot()
92
+ sphinx_plot(P)
93
+
94
+ If we move slightly the axis, we get a goblet-like surface::
95
+
96
+ sage: revolution_plot3d(f, (u,0,2), axis=(1,0.2),
97
+ ....: show_curve=True, opacity=0.5).show(aspect_ratio=(1,1,1))
98
+
99
+ .. PLOT::
100
+
101
+ u = var('u')
102
+ f = u**2
103
+ P = revolution_plot3d(f, (u,0,2), axis=(1,0.2), show_curve=True, opacity=0.5).plot()
104
+ sphinx_plot(P)
105
+
106
+ A common problem in calculus books, find the volume within the following revolution solid::
107
+
108
+ sage: line = u
109
+ sage: parabola = u^2
110
+ sage: sur1 = revolution_plot3d(line, (u,0,1), opacity=0.5, rgbcolor=(1,0.5,0),
111
+ ....: show_curve=True, parallel_axis='x')
112
+ sage: sur2 = revolution_plot3d(parabola, (u,0,1), opacity=0.5, rgbcolor=(0,1,0),
113
+ ....: show_curve=True, parallel_axis='x')
114
+ sage: (sur1 + sur2).show()
115
+
116
+ .. PLOT::
117
+
118
+ u = var('u')
119
+ line = u
120
+ parabola = u**2
121
+ sur1 = revolution_plot3d(line, (u,0,1), opacity=0.5, rgbcolor=(1,0.5,0), show_curve=True, parallel_axis='x')
122
+ sur2 = revolution_plot3d(parabola, (u,0,1), opacity=0.5, rgbcolor=(0,1,0), show_curve=True, parallel_axis='x')
123
+ P = sur1 + sur2
124
+ sphinx_plot(P)
125
+
126
+ Now let's revolve a parametrically defined circle. We can play with the topology of the surface by changing the axis,
127
+ an axis in `(0,0)` (as the previous one) will produce a sphere-like surface::
128
+
129
+ sage: u = var('u')
130
+ sage: circle = (cos(u), sin(u))
131
+ sage: revolution_plot3d(circle, (u,0,2*pi), axis=(0,0),
132
+ ....: show_curve=True, opacity=0.5).show(aspect_ratio=(1,1,1))
133
+
134
+ .. PLOT::
135
+
136
+ u = var('u')
137
+ circle = (cos(u), sin(u))
138
+ P = revolution_plot3d(circle, (u,0,2*pi), axis=(0,0), show_curve=True, opacity=0.5)
139
+ sphinx_plot(P)
140
+
141
+ An axis on `(0,y)` will produce a cylinder-like surface::
142
+
143
+ sage: revolution_plot3d(circle, (u,0,2*pi), axis=(0,2),
144
+ ....: show_curve=True, opacity=0.5).show(aspect_ratio=(1,1,1))
145
+
146
+ .. PLOT::
147
+
148
+ u = var('u')
149
+ circle = (cos(u), sin(u))
150
+ P = revolution_plot3d(circle, (u,0,2*pi), axis=(0,2), show_curve=True, opacity=0.5)
151
+ sphinx_plot(P)
152
+
153
+ And any other axis will produce a torus-like surface::
154
+
155
+ sage: revolution_plot3d(circle, (u,0,2*pi), axis=(2,0),
156
+ ....: show_curve=True, opacity=0.5).show(aspect_ratio=(1,1,1))
157
+
158
+ .. PLOT::
159
+
160
+ u = var('u')
161
+ circle = (cos(u), sin(u))
162
+ P = revolution_plot3d(circle, (u,0,2*pi), axis=(2,0), show_curve=True, opacity=0.5)
163
+ sphinx_plot(P)
164
+
165
+ Now, we can get another goblet-like surface by revolving a curve in 3d::
166
+
167
+ sage: u = var('u')
168
+ sage: curve = (u, cos(4*u), u^2)
169
+ sage: P = revolution_plot3d(curve, (u,0,2), parallel_axis='z', axis=(1,.2),
170
+ ....: show_curve=True, opacity=0.5)
171
+ sage: P.show(aspect_ratio=(1,1,1))
172
+
173
+ .. PLOT::
174
+
175
+ u = var('u')
176
+ curve = (u, cos(4*u), u**2)
177
+ P = revolution_plot3d(curve, (u,0,2), show_curve=True, parallel_axis='z', axis=(1,.2), opacity=0.5)
178
+ sphinx_plot(P)
179
+
180
+ A curvy curve with only a quarter turn::
181
+
182
+ sage: u = var('u')
183
+ sage: curve = (sin(3*u), .8*cos(4*u), cos(u))
184
+ sage: revolution_plot3d(curve, (u,0,pi), (0,pi/2), parallel_axis='z',
185
+ ....: show_curve=True, opacity=0.5).show(aspect_ratio=(1,1,1),
186
+ ....: frame=False)
187
+
188
+ .. PLOT::
189
+
190
+ u = var('u')
191
+ curve = (sin(3*u), .8*cos(4*u), cos(u))
192
+ P = revolution_plot3d(curve, (u,0,pi), (0,pi/2), show_curve=True, parallel_axis='z', opacity=0.5)
193
+ sphinx_plot(P)
194
+
195
+ One can also color the surface using a coloring function of two
196
+ parameters and a colormap as follows. Note that the coloring
197
+ function must take values in the interval `[0,1]`. ::
198
+
199
+ sage: u, phi = var('u,phi')
200
+ sage: def cf(u, phi): return sin(phi+u) ^ 2
201
+ sage: curve = (1+u^2/4, 0, u)
202
+ sage: revolution_plot3d(curve, (u,-2,2), (0,2*pi), parallel_axis='z',
203
+ ....: color=(cf, colormaps.PiYG)).show(aspect_ratio=(1,1,1))
204
+
205
+ .. PLOT::
206
+
207
+ u, phi = var('u,phi')
208
+ def cf(u, phi): return sin(phi+u) ** 2
209
+ curve = (1+u**2/4, 0, u)
210
+ P = revolution_plot3d(curve, (u,-2,2), (0,2*pi), parallel_axis='z', color=(cf, colormaps.PiYG))
211
+ sphinx_plot(P)
212
+
213
+ The first parameter of the coloring function will be identified with the
214
+ parameter of the curve, and the second with the angle parameter.
215
+
216
+ Another colored example, illustrating that one can use (colormap, color function) instead of (color function, colormap)::
217
+
218
+ sage: u, phi = var('u,phi')
219
+ sage: def cf(u, phi): return float(2 * u / pi) % 1
220
+ sage: curve = (sin(u), 0, u)
221
+ sage: revolution_plot3d(curve, (u,0,pi), (0,2*pi), parallel_axis='z',
222
+ ....: color=(colormaps.brg, cf)).show(aspect_ratio=1)
223
+
224
+ .. PLOT::
225
+
226
+ u, phi = var('u,phi')
227
+ def cf(u, phi): return float(2 * u / pi) % 1
228
+ curve = (sin(u), 0, u)
229
+ P = revolution_plot3d(curve, (u,0,pi), (0,2*pi), parallel_axis='z', color=(colormaps.brg, cf))
230
+ sphinx_plot(P)
231
+ """
232
+ from sage.symbolic.ring import SR
233
+ from sage.symbolic.constants import pi
234
+ from sage.misc.functional import sqrt
235
+ from sage.functions.trig import sin
236
+ from sage.functions.trig import cos
237
+ from sage.functions.trig import atan2
238
+
239
+ if parallel_axis not in ['x', 'y', 'z']:
240
+ raise ValueError("parallel_axis must be either 'x', 'y', or 'z'")
241
+
242
+ vart = trange[0]
243
+
244
+ if str(vart) == 'phi':
245
+ phi = SR.var('fi')
246
+ else:
247
+ phi = SR.var('phi')
248
+
249
+ if phirange is None: # this if-else provides a phirange
250
+ phirange = (phi, 0, 2 * pi)
251
+ elif len(phirange) == 3:
252
+ phi = phirange[0]
253
+ else:
254
+ phirange = (phi, phirange[0], phirange[1])
255
+
256
+ if isinstance(curve, (tuple, list)):
257
+ # this if-else provides a vector v to be plotted
258
+ # if curve is a tuple or a list of length 2, it is interpreted as a parametric curve
259
+ # in the x-z plane.
260
+ # if it is of length 3 it is interpreted as a parametric curve in 3d space
261
+
262
+ if len(curve) == 2:
263
+ x = curve[0]
264
+ y = 0
265
+ z = curve[1]
266
+ elif len(curve) == 3:
267
+ x = curve[0]
268
+ y = curve[1]
269
+ z = curve[2]
270
+ else:
271
+ x = vart
272
+ y = 0
273
+ z = curve
274
+
275
+ phase = 0
276
+ if parallel_axis == 'z':
277
+ x0 = axis[0]
278
+ y0 = axis[1]
279
+ # (0,0) must be handled separately for the phase value
280
+ if x0 != 0 or y0 != 0:
281
+ phase = atan2(y - y0, x - x0)
282
+ R = sqrt((x-x0)**2 + (y-y0)**2)
283
+ v = (R*cos(phi+phase)+x0, R*sin(phi+phase)+y0, z)
284
+ elif parallel_axis == 'x':
285
+ y0 = axis[0]
286
+ z0 = axis[1]
287
+ # (0,0) must be handled separately for the phase value
288
+ if z0 != 0 or y0 != 0:
289
+ phase = atan2(z - z0, y - y0)
290
+ R = sqrt((y-y0)**2 + (z-z0)**2)
291
+ v = (x, R*cos(phi+phase)+y0, R*sin(phi+phase)+z0)
292
+ elif parallel_axis == 'y':
293
+ x0 = axis[0]
294
+ z0 = axis[1]
295
+ # (0,0) must be handled separately for the phase value
296
+ if z0 != 0 or x0 != 0:
297
+ phase = atan2(z - z0, x - x0)
298
+ R = sqrt((x-x0)**2 + (z-z0)**2)
299
+ v = (R*cos(phi+phase)+x0, y, R*sin(phi+phase)+z0)
300
+
301
+ if print_vector:
302
+ print(v)
303
+
304
+ if show_curve:
305
+ curveplot = parametric_plot3d((x, y, z), trange, thickness=2,
306
+ rgbcolor=(1, 0, 0))
307
+ return parametric_plot3d(v, trange, phirange, **kwds) + curveplot
308
+
309
+ return parametric_plot3d(v, trange, phirange, **kwds)
@@ -0,0 +1,22 @@
1
+ # sage_setup: distribution = sagemath-plot
2
+ from sage.plot.plot3d.parametric_surface cimport ParametricSurface
3
+
4
+
5
+ cdef class Cone(ParametricSurface):
6
+ cdef double radius
7
+ cdef double height
8
+ cdef bint closed
9
+
10
+
11
+ cdef class Cylinder(ParametricSurface):
12
+ cdef double radius
13
+ cdef double height
14
+ cdef bint closed
15
+
16
+
17
+ cdef class Sphere(ParametricSurface):
18
+ cdef double radius
19
+
20
+
21
+ cdef class Torus(ParametricSurface):
22
+ cdef double R, r