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.
- passagemath_plot-10.6.31rc3.dist-info/METADATA +172 -0
- passagemath_plot-10.6.31rc3.dist-info/RECORD +81 -0
- passagemath_plot-10.6.31rc3.dist-info/WHEEL +6 -0
- passagemath_plot-10.6.31rc3.dist-info/top_level.txt +2 -0
- passagemath_plot.libs/libgfortran-e1b7dfc8.so.5.0.0 +0 -0
- passagemath_plot.libs/libgsl-e3525837.so.28.0.0 +0 -0
- passagemath_plot.libs/libopenblasp-r0-4c5b64b1.3.29.so +0 -0
- sage/all__sagemath_plot.py +15 -0
- sage/ext_data/threejs/animation.css +195 -0
- sage/ext_data/threejs/animation.html +85 -0
- sage/ext_data/threejs/animation.js +273 -0
- sage/ext_data/threejs/fat_lines.js +48 -0
- sage/ext_data/threejs/threejs-version.txt +1 -0
- sage/ext_data/threejs/threejs_template.html +597 -0
- sage/interfaces/all__sagemath_plot.py +1 -0
- sage/interfaces/gnuplot.py +196 -0
- sage/interfaces/jmoldata.py +208 -0
- sage/interfaces/povray.py +56 -0
- sage/plot/all.py +42 -0
- sage/plot/animate.py +1796 -0
- sage/plot/arc.py +504 -0
- sage/plot/arrow.py +671 -0
- sage/plot/bar_chart.py +205 -0
- sage/plot/bezier_path.py +400 -0
- sage/plot/circle.py +435 -0
- sage/plot/colors.py +1606 -0
- sage/plot/complex_plot.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/plot/complex_plot.pyx +1446 -0
- sage/plot/contour_plot.py +1792 -0
- sage/plot/density_plot.py +318 -0
- sage/plot/disk.py +373 -0
- sage/plot/ellipse.py +375 -0
- sage/plot/graphics.py +3580 -0
- sage/plot/histogram.py +354 -0
- sage/plot/hyperbolic_arc.py +404 -0
- sage/plot/hyperbolic_polygon.py +416 -0
- sage/plot/hyperbolic_regular_polygon.py +296 -0
- sage/plot/line.py +626 -0
- sage/plot/matrix_plot.py +629 -0
- sage/plot/misc.py +509 -0
- sage/plot/multigraphics.py +1294 -0
- sage/plot/plot.py +4183 -0
- sage/plot/plot3d/all.py +23 -0
- sage/plot/plot3d/base.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/plot/plot3d/base.pxd +12 -0
- sage/plot/plot3d/base.pyx +3378 -0
- sage/plot/plot3d/implicit_plot3d.py +659 -0
- sage/plot/plot3d/implicit_surface.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/plot/plot3d/implicit_surface.pyx +1453 -0
- sage/plot/plot3d/index_face_set.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/plot/plot3d/index_face_set.pxd +32 -0
- sage/plot/plot3d/index_face_set.pyx +1873 -0
- sage/plot/plot3d/introduction.py +131 -0
- sage/plot/plot3d/list_plot3d.py +649 -0
- sage/plot/plot3d/parametric_plot3d.py +1130 -0
- sage/plot/plot3d/parametric_surface.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/plot/plot3d/parametric_surface.pxd +12 -0
- sage/plot/plot3d/parametric_surface.pyx +893 -0
- sage/plot/plot3d/platonic.py +601 -0
- sage/plot/plot3d/plot3d.py +1442 -0
- sage/plot/plot3d/plot_field3d.py +162 -0
- sage/plot/plot3d/point_c.pxi +148 -0
- sage/plot/plot3d/revolution_plot3d.py +309 -0
- sage/plot/plot3d/shapes.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/plot/plot3d/shapes.pxd +22 -0
- sage/plot/plot3d/shapes.pyx +1382 -0
- sage/plot/plot3d/shapes2.py +1512 -0
- sage/plot/plot3d/tachyon.py +1779 -0
- sage/plot/plot3d/texture.py +453 -0
- sage/plot/plot3d/transform.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/plot/plot3d/transform.pxd +21 -0
- sage/plot/plot3d/transform.pyx +268 -0
- sage/plot/plot3d/tri_plot.py +589 -0
- sage/plot/plot_field.py +362 -0
- sage/plot/point.py +624 -0
- sage/plot/polygon.py +562 -0
- sage/plot/primitive.py +249 -0
- sage/plot/scatter_plot.py +199 -0
- sage/plot/step.py +85 -0
- sage/plot/streamline_plot.py +328 -0
- sage/plot/text.py +432 -0
|
@@ -0,0 +1,601 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-plot
|
|
2
|
+
r"""
|
|
3
|
+
Platonic solids
|
|
4
|
+
|
|
5
|
+
EXAMPLES: The five platonic solids in a row:
|
|
6
|
+
|
|
7
|
+
::
|
|
8
|
+
|
|
9
|
+
sage: G = tetrahedron((0,-3.5,0), color='blue') + cube((0,-2,0),color=(.25,0,.5))
|
|
10
|
+
sage: G += octahedron(color='red') + dodecahedron((0,2,0), color='orange')
|
|
11
|
+
sage: G += icosahedron(center=(0,4,0), color='yellow')
|
|
12
|
+
sage: G.show(aspect_ratio=[1,1,1])
|
|
13
|
+
|
|
14
|
+
.. PLOT::
|
|
15
|
+
|
|
16
|
+
G = tetrahedron((0,-3.5,0), color='blue') + cube((0,-2,0),color=(.25,0,.5))
|
|
17
|
+
G += octahedron(color='red') + dodecahedron((0,2,0), color='orange')
|
|
18
|
+
G += icosahedron(center=(0,4,0), color='yellow')
|
|
19
|
+
sphinx_plot(G)
|
|
20
|
+
|
|
21
|
+
All the platonic solids in the same place::
|
|
22
|
+
|
|
23
|
+
sage: G = tetrahedron(color='blue',opacity=0.7)
|
|
24
|
+
sage: G += cube(color=(.25,0,.5), opacity=0.7)
|
|
25
|
+
sage: G += octahedron(color='red', opacity=0.7)
|
|
26
|
+
sage: G += dodecahedron(color='orange', opacity=0.7) + icosahedron(opacity=0.7)
|
|
27
|
+
sage: G.show(aspect_ratio=[1,1,1])
|
|
28
|
+
|
|
29
|
+
.. PLOT::
|
|
30
|
+
|
|
31
|
+
G = tetrahedron(color='blue',opacity=0.7)
|
|
32
|
+
G += cube(color=(.25,0,.5), opacity=0.7)
|
|
33
|
+
G += octahedron(color='red', opacity=0.7)
|
|
34
|
+
G += dodecahedron(color='orange', opacity=0.7) + icosahedron(opacity=0.7)
|
|
35
|
+
sphinx_plot(G)
|
|
36
|
+
|
|
37
|
+
Display nice faces only::
|
|
38
|
+
|
|
39
|
+
sage: icosahedron().stickers(['red','blue'], .075, .1)
|
|
40
|
+
Graphics3d Object
|
|
41
|
+
|
|
42
|
+
.. PLOT::
|
|
43
|
+
|
|
44
|
+
sphinx_plot(icosahedron().stickers(['red','blue'], .075, .1))
|
|
45
|
+
|
|
46
|
+
AUTHORS:
|
|
47
|
+
|
|
48
|
+
- Robert Bradshaw (2007, 2008): initial version
|
|
49
|
+
|
|
50
|
+
- William Stein
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# ****************************************************************************
|
|
55
|
+
# Copyright (C) 2007 Robert Bradshaw <robertwb@math.washington.edu>
|
|
56
|
+
#
|
|
57
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
58
|
+
#
|
|
59
|
+
# This code is distributed in the hope that it will be useful,
|
|
60
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
61
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
62
|
+
# General Public License for more details.
|
|
63
|
+
#
|
|
64
|
+
# The full text of the GPL is available at:
|
|
65
|
+
#
|
|
66
|
+
# https://www.gnu.org/licenses/
|
|
67
|
+
# ****************************************************************************
|
|
68
|
+
|
|
69
|
+
from sage.rings.real_double import RDF
|
|
70
|
+
from sage.matrix.constructor import matrix
|
|
71
|
+
from sage.misc.decorators import rename_keyword
|
|
72
|
+
from .shapes import Box, ColorCube
|
|
73
|
+
from .shapes2 import frame3d
|
|
74
|
+
from .index_face_set import IndexFaceSet
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def index_face_set(face_list, point_list, enclosed, **kwds):
|
|
78
|
+
"""
|
|
79
|
+
Helper function that creates ``IndexFaceSet`` object for the
|
|
80
|
+
tetrahedron, dodecahedron, and icosahedron.
|
|
81
|
+
|
|
82
|
+
INPUT:
|
|
83
|
+
|
|
84
|
+
- ``face_list`` -- list of faces, given explicitly from the
|
|
85
|
+
solid invocation
|
|
86
|
+
|
|
87
|
+
- ``point_list`` -- list of points, given explicitly from the
|
|
88
|
+
solid invocation
|
|
89
|
+
|
|
90
|
+
- ``enclosed`` -- boolean (default: ``True`` for these solids)
|
|
91
|
+
|
|
92
|
+
TESTS:
|
|
93
|
+
|
|
94
|
+
Verify that these are working and passing on keywords::
|
|
95
|
+
|
|
96
|
+
sage: tetrahedron(center=(2,0,0),size=2,color='red')
|
|
97
|
+
Graphics3d Object
|
|
98
|
+
|
|
99
|
+
::
|
|
100
|
+
|
|
101
|
+
sage: dodecahedron(center=(2,0,0),size=2,color='red')
|
|
102
|
+
Graphics3d Object
|
|
103
|
+
|
|
104
|
+
::
|
|
105
|
+
|
|
106
|
+
sage: icosahedron(center=(2,0,0),size=2,color='red')
|
|
107
|
+
Graphics3d Object
|
|
108
|
+
"""
|
|
109
|
+
if 'center' in kwds:
|
|
110
|
+
center = kwds['center']
|
|
111
|
+
del kwds['center']
|
|
112
|
+
else:
|
|
113
|
+
center = (0, 0, 0)
|
|
114
|
+
if 'size' in kwds:
|
|
115
|
+
size = kwds['size']
|
|
116
|
+
del kwds['size']
|
|
117
|
+
else:
|
|
118
|
+
size = 1
|
|
119
|
+
I = IndexFaceSet(face_list, point_list, enclosed=enclosed, **kwds)
|
|
120
|
+
return prep(I, center, size, kwds)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def prep(G, center, size, kwds):
|
|
124
|
+
"""
|
|
125
|
+
Helper function that scales and translates the platonic
|
|
126
|
+
solid, and passes extra keywords on.
|
|
127
|
+
|
|
128
|
+
INPUT:
|
|
129
|
+
|
|
130
|
+
- ``center`` -- 3-tuple indicating the center (default: the origin
|
|
131
|
+
`(0,0,0)`, passed from :func:`index_face_set`)
|
|
132
|
+
|
|
133
|
+
- ``size`` -- number indicating amount to scale by (default: 1,
|
|
134
|
+
passed from :func:`index_face_set`)
|
|
135
|
+
|
|
136
|
+
- ``kwds`` -- dictionary of keywords, passed from solid
|
|
137
|
+
invocation by :func:`index_face_set`
|
|
138
|
+
|
|
139
|
+
TESTS:
|
|
140
|
+
|
|
141
|
+
Verify that scaling and moving the center work together properly,
|
|
142
|
+
and that keywords are passed (see :issue:`10796`)::
|
|
143
|
+
|
|
144
|
+
sage: octahedron(center=(2,0,0),size=2,color='red')
|
|
145
|
+
Graphics3d Object
|
|
146
|
+
"""
|
|
147
|
+
kwds['threejs_flat_shading'] = True
|
|
148
|
+
G._set_extra_kwds(kwds)
|
|
149
|
+
if size != 1:
|
|
150
|
+
G = G.scale(size)
|
|
151
|
+
if center != (0, 0, 0):
|
|
152
|
+
G = G.translate(center)
|
|
153
|
+
return G
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
@rename_keyword(alpha='opacity')
|
|
157
|
+
def tetrahedron(center=(0, 0, 0), size=1, **kwds):
|
|
158
|
+
"""
|
|
159
|
+
A 3d tetrahedron.
|
|
160
|
+
|
|
161
|
+
INPUT:
|
|
162
|
+
|
|
163
|
+
- ``center`` -- (default: (0,0,0))
|
|
164
|
+
|
|
165
|
+
- ``size`` -- (default: 1)
|
|
166
|
+
|
|
167
|
+
- ``color`` -- string (``'red'``, ``'green'``, etc)
|
|
168
|
+
or a tuple (r, g, b) with r, g, b numbers between 0 and 1
|
|
169
|
+
|
|
170
|
+
- ``opacity`` -- (default: 1) if less than 1 then is
|
|
171
|
+
transparent
|
|
172
|
+
|
|
173
|
+
EXAMPLES: A default colored tetrahedron at the origin::
|
|
174
|
+
|
|
175
|
+
sage: tetrahedron()
|
|
176
|
+
Graphics3d Object
|
|
177
|
+
|
|
178
|
+
.. PLOT::
|
|
179
|
+
|
|
180
|
+
sphinx_plot(tetrahedron())
|
|
181
|
+
|
|
182
|
+
A transparent green tetrahedron in front of a solid red one::
|
|
183
|
+
|
|
184
|
+
sage: tetrahedron(opacity=0.8, color='green') + tetrahedron((-2,1,0),color='red')
|
|
185
|
+
Graphics3d Object
|
|
186
|
+
|
|
187
|
+
.. PLOT::
|
|
188
|
+
|
|
189
|
+
sphinx_plot(tetrahedron(opacity=0.8, color='green') + tetrahedron((-2,1,0),color='red'))
|
|
190
|
+
|
|
191
|
+
A translucent tetrahedron sharing space with a sphere::
|
|
192
|
+
|
|
193
|
+
sage: tetrahedron(color='yellow',opacity=0.7) + sphere(size=.5, color='red')
|
|
194
|
+
Graphics3d Object
|
|
195
|
+
|
|
196
|
+
.. PLOT::
|
|
197
|
+
|
|
198
|
+
sphinx_plot(tetrahedron(color='yellow',opacity=0.7) + sphere(size = .5, color='red'))
|
|
199
|
+
|
|
200
|
+
A big tetrahedron::
|
|
201
|
+
|
|
202
|
+
sage: tetrahedron(size=10)
|
|
203
|
+
Graphics3d Object
|
|
204
|
+
|
|
205
|
+
.. PLOT::
|
|
206
|
+
|
|
207
|
+
sphinx_plot(tetrahedron(size=10))
|
|
208
|
+
|
|
209
|
+
A wide tetrahedron::
|
|
210
|
+
|
|
211
|
+
sage: tetrahedron(aspect_ratio=[1,1,1]).scale((4,4,1))
|
|
212
|
+
Graphics3d Object
|
|
213
|
+
|
|
214
|
+
.. PLOT::
|
|
215
|
+
|
|
216
|
+
sphinx_plot(tetrahedron(aspect_ratio=[1,1,1]).scale((4,4,1)))
|
|
217
|
+
|
|
218
|
+
A red and blue tetrahedron touching noses::
|
|
219
|
+
|
|
220
|
+
sage: tetrahedron(color='red') + tetrahedron((0,0,-2)).scale([1,1,-1])
|
|
221
|
+
Graphics3d Object
|
|
222
|
+
|
|
223
|
+
.. PLOT::
|
|
224
|
+
|
|
225
|
+
sphinx_plot(tetrahedron(color='red') + tetrahedron((0,0,-2)).scale([1,1,-1]))
|
|
226
|
+
|
|
227
|
+
A Dodecahedral complex of 5 tetrahedra (a more elaborate example
|
|
228
|
+
from Peter Jipsen)::
|
|
229
|
+
|
|
230
|
+
sage: from math import pi
|
|
231
|
+
sage: v = (sqrt(5.)/2-5/6, 5/6*sqrt(3.)-sqrt(15.)/2, sqrt(5.)/3)
|
|
232
|
+
sage: t = acos(sqrt(5.)/3)/2
|
|
233
|
+
sage: t1 = tetrahedron(aspect_ratio=(1,1,1), opacity=0.5).rotateZ(t)
|
|
234
|
+
sage: t2 = tetrahedron(color='red', opacity=0.5).rotateZ(t).rotate(v,2*pi/5)
|
|
235
|
+
sage: t3 = tetrahedron(color='green', opacity=0.5).rotateZ(t).rotate(v,4*pi/5)
|
|
236
|
+
sage: t4 = tetrahedron(color='yellow', opacity=0.5).rotateZ(t).rotate(v,6*pi/5)
|
|
237
|
+
sage: t5 = tetrahedron(color='orange', opacity=0.5).rotateZ(t).rotate(v,8*pi/5)
|
|
238
|
+
sage: show(t1+t2+t3+t4+t5, frame=False, zoom=1.3)
|
|
239
|
+
|
|
240
|
+
.. PLOT::
|
|
241
|
+
|
|
242
|
+
v=(sqrt(5.)/2-5/6, 5/6*sqrt(3.)-sqrt(15.)/2, sqrt(5.)/3)
|
|
243
|
+
t=acos(sqrt(5.)/3)/2
|
|
244
|
+
t1=tetrahedron(aspect_ratio=(1,1,1), opacity=0.5).rotateZ(t)
|
|
245
|
+
t2=tetrahedron(color='red', opacity=0.5).rotateZ(t).rotate(v,2*pi/5)
|
|
246
|
+
t3=tetrahedron(color='green', opacity=0.5).rotateZ(t).rotate(v,4*pi/5)
|
|
247
|
+
t4=tetrahedron(color='yellow', opacity=0.5).rotateZ(t).rotate(v,6*pi/5)
|
|
248
|
+
t5=tetrahedron(color='orange', opacity=0.5).rotateZ(t).rotate(v,8*pi/5)
|
|
249
|
+
sphinx_plot(t1+t2+t3+t4+t5)
|
|
250
|
+
|
|
251
|
+
AUTHORS:
|
|
252
|
+
|
|
253
|
+
- Robert Bradshaw and William Stein
|
|
254
|
+
"""
|
|
255
|
+
RR = RDF
|
|
256
|
+
one = RR.one()
|
|
257
|
+
sqrt2 = RR(2).sqrt()
|
|
258
|
+
sqrt6 = RR(6).sqrt()
|
|
259
|
+
point_list = [(0, 0, 1),
|
|
260
|
+
(2*sqrt2/3, 0, -one/3),
|
|
261
|
+
(-sqrt2/3, sqrt6/3, -one/3),
|
|
262
|
+
(-sqrt2/3, -sqrt6/3, -one/3)]
|
|
263
|
+
face_list = [[0,1,2],[1,3,2],[0,2,3],[0,3,1]]
|
|
264
|
+
if 'aspect_ratio' not in kwds:
|
|
265
|
+
kwds['aspect_ratio'] = [1, 1, 1]
|
|
266
|
+
return index_face_set(face_list, point_list, enclosed=True, center=center, size=size, **kwds)
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
@rename_keyword(alpha='opacity')
|
|
270
|
+
def cube(center=(0, 0, 0), size=1, color=None, frame_thickness=0,
|
|
271
|
+
frame_color=None, **kwds):
|
|
272
|
+
"""
|
|
273
|
+
A 3D cube centered at the origin with default side lengths 1.
|
|
274
|
+
|
|
275
|
+
INPUT:
|
|
276
|
+
|
|
277
|
+
- ``center`` -- (default: (0,0,0))
|
|
278
|
+
|
|
279
|
+
- ``size`` -- (default: 1) the side lengths of the cube
|
|
280
|
+
|
|
281
|
+
- ``color`` -- string that describes a color; this
|
|
282
|
+
can also be a list of 3-tuples or strings length 6 or 3, in which
|
|
283
|
+
case the faces (and oppositive faces) are colored
|
|
284
|
+
|
|
285
|
+
- ``frame_thickness`` -- (default: 0) if positive,
|
|
286
|
+
then thickness of the frame
|
|
287
|
+
|
|
288
|
+
- ``frame_color`` -- (default: ``None``) if given, gives
|
|
289
|
+
the color of the frame
|
|
290
|
+
|
|
291
|
+
- ``opacity`` -- (default: 1) if less than 1 then it's transparent
|
|
292
|
+
|
|
293
|
+
EXAMPLES:
|
|
294
|
+
|
|
295
|
+
A simple cube::
|
|
296
|
+
|
|
297
|
+
sage: cube()
|
|
298
|
+
Graphics3d Object
|
|
299
|
+
|
|
300
|
+
.. PLOT::
|
|
301
|
+
|
|
302
|
+
sphinx_plot(cube())
|
|
303
|
+
|
|
304
|
+
A red cube::
|
|
305
|
+
|
|
306
|
+
sage: cube(color='red')
|
|
307
|
+
Graphics3d Object
|
|
308
|
+
|
|
309
|
+
.. PLOT::
|
|
310
|
+
|
|
311
|
+
sphinx_plot(cube(color='red'))
|
|
312
|
+
|
|
313
|
+
A transparent grey cube that contains a red cube::
|
|
314
|
+
|
|
315
|
+
sage: cube(opacity=0.8, color='grey') + cube(size=3/4)
|
|
316
|
+
Graphics3d Object
|
|
317
|
+
|
|
318
|
+
.. PLOT::
|
|
319
|
+
|
|
320
|
+
sphinx_plot(cube(opacity=0.8, color='grey') + cube(size=3/4))
|
|
321
|
+
|
|
322
|
+
A transparent colored cube::
|
|
323
|
+
|
|
324
|
+
sage: cube(color=['red', 'green', 'blue'], opacity=0.5)
|
|
325
|
+
Graphics3d Object
|
|
326
|
+
|
|
327
|
+
.. PLOT::
|
|
328
|
+
|
|
329
|
+
sphinx_plot(cube(color=['red', 'green', 'blue'], opacity=0.5))
|
|
330
|
+
|
|
331
|
+
A bunch of random cubes::
|
|
332
|
+
|
|
333
|
+
sage: v = [(random(), random(), random()) for _ in [1..30]]
|
|
334
|
+
sage: sum([cube((10*a,10*b,10*c), size=random()/3, color=(a,b,c)) for a,b,c in v])
|
|
335
|
+
Graphics3d Object
|
|
336
|
+
|
|
337
|
+
.. PLOT::
|
|
338
|
+
|
|
339
|
+
v = [(random(), random(), random()) for _ in range(30)]
|
|
340
|
+
sphinx_plot(sum([cube((10*a,10*b,10*c), size=random()/3, color=(a,b,c)) for a,b,c in v]))
|
|
341
|
+
|
|
342
|
+
Non-square cubes (boxes)::
|
|
343
|
+
|
|
344
|
+
sage: cube(aspect_ratio=[1,1,1]).scale([1,2,3])
|
|
345
|
+
Graphics3d Object
|
|
346
|
+
|
|
347
|
+
.. PLOT::
|
|
348
|
+
|
|
349
|
+
sphinx_plot(cube(aspect_ratio=[1,1,1]).scale([1,2,3]))
|
|
350
|
+
|
|
351
|
+
::
|
|
352
|
+
|
|
353
|
+
sage: cube(color=['red', 'blue', 'green'],aspect_ratio=[1,1,1]).scale([1,2,3])
|
|
354
|
+
Graphics3d Object
|
|
355
|
+
|
|
356
|
+
.. PLOT::
|
|
357
|
+
|
|
358
|
+
sphinx_plot(cube(color=['red', 'blue', 'green'],aspect_ratio=[1,1,1]).scale([1,2,3]))
|
|
359
|
+
|
|
360
|
+
And one that is colored::
|
|
361
|
+
|
|
362
|
+
sage: cube(color=['red', 'blue', 'green', 'black', 'white', 'orange'],
|
|
363
|
+
....: aspect_ratio=[1,1,1]).scale([1,2,3])
|
|
364
|
+
Graphics3d Object
|
|
365
|
+
|
|
366
|
+
.. PLOT::
|
|
367
|
+
|
|
368
|
+
sphinx_plot(cube(color=['red', 'blue', 'green', 'black', 'white', 'orange'],aspect_ratio=[1,1,1]).scale([1,2,3]))
|
|
369
|
+
|
|
370
|
+
A nice translucent color cube with a frame::
|
|
371
|
+
|
|
372
|
+
sage: c = cube(color=['red', 'blue', 'green'], frame=False, frame_thickness=2,
|
|
373
|
+
....: frame_color='brown', opacity=0.8)
|
|
374
|
+
sage: c
|
|
375
|
+
Graphics3d Object
|
|
376
|
+
|
|
377
|
+
.. PLOT::
|
|
378
|
+
|
|
379
|
+
c = cube(color=['red', 'blue', 'green'], frame=False, frame_thickness=2,frame_color='brown', opacity=0.8)
|
|
380
|
+
sphinx_plot(c)
|
|
381
|
+
|
|
382
|
+
A raytraced color cube with frame and transparency::
|
|
383
|
+
|
|
384
|
+
sage: c.show(viewer='tachyon')
|
|
385
|
+
|
|
386
|
+
This shows :issue:`11272` has been fixed::
|
|
387
|
+
|
|
388
|
+
sage: cube(center=(10, 10, 10), size=0.5).bounding_box()
|
|
389
|
+
((9.75, 9.75, 9.75), (10.25, 10.25, 10.25))
|
|
390
|
+
|
|
391
|
+
AUTHORS:
|
|
392
|
+
|
|
393
|
+
- William Stein
|
|
394
|
+
"""
|
|
395
|
+
if isinstance(color, (list, tuple)) and len(color) > 0 and isinstance(color[0], (list, tuple, str)):
|
|
396
|
+
B = ColorCube(size=[0.5,0.5,0.5], colors=color, **kwds)
|
|
397
|
+
else:
|
|
398
|
+
if color is not None:
|
|
399
|
+
kwds['color'] = color
|
|
400
|
+
B = Box(0.5, 0.5, 0.5, **kwds)
|
|
401
|
+
if frame_thickness > 0:
|
|
402
|
+
if frame_color is None:
|
|
403
|
+
B += frame3d((-0.5,-0.5,-0.5),(0.5,0.5,0.5), thickness=frame_thickness)
|
|
404
|
+
else:
|
|
405
|
+
B += frame3d((-0.5,-0.5,-0.5),(0.5,0.5,0.5), thickness=frame_thickness, color=frame_color)
|
|
406
|
+
return prep(B, center, size, kwds)
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
@rename_keyword(alpha='opacity')
|
|
410
|
+
def octahedron(center=(0, 0, 0), size=1, **kwds):
|
|
411
|
+
r"""
|
|
412
|
+
Return an octahedron.
|
|
413
|
+
|
|
414
|
+
INPUT:
|
|
415
|
+
|
|
416
|
+
- ``center`` -- (default: (0,0,0))
|
|
417
|
+
|
|
418
|
+
- ``size`` -- (default: 1)
|
|
419
|
+
|
|
420
|
+
- ``color`` -- string that describes a color; this
|
|
421
|
+
can also be a list of 3-tuples or strings length 6 or 3, in which
|
|
422
|
+
case the faces (and oppositive faces) are colored
|
|
423
|
+
|
|
424
|
+
- ``opacity`` -- (default: 1) if less than 1 then is transparent
|
|
425
|
+
|
|
426
|
+
EXAMPLES::
|
|
427
|
+
|
|
428
|
+
sage: G = octahedron((1,4,3), color='orange')
|
|
429
|
+
sage: G += octahedron((0,2,1), size=2, opacity=0.6)
|
|
430
|
+
sage: G
|
|
431
|
+
Graphics3d Object
|
|
432
|
+
|
|
433
|
+
.. PLOT::
|
|
434
|
+
|
|
435
|
+
G = octahedron((1,4,3), color='orange')
|
|
436
|
+
G += octahedron((0,2,1), size=2, opacity=0.6)
|
|
437
|
+
sphinx_plot(G)
|
|
438
|
+
"""
|
|
439
|
+
kwds['enclosed'] = True
|
|
440
|
+
if 'aspect_ratio' not in kwds:
|
|
441
|
+
kwds['aspect_ratio'] = [1, 1, 1]
|
|
442
|
+
return prep(Box(1, 1, 1).dual(**kwds), center, size, kwds)
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
@rename_keyword(alpha='opacity')
|
|
446
|
+
def dodecahedron(center=(0, 0, 0), size=1, **kwds):
|
|
447
|
+
r"""
|
|
448
|
+
A dodecahedron.
|
|
449
|
+
|
|
450
|
+
INPUT:
|
|
451
|
+
|
|
452
|
+
- ``center`` -- (default: (0,0,0))
|
|
453
|
+
|
|
454
|
+
- ``size`` -- (default: 1)
|
|
455
|
+
|
|
456
|
+
- ``color`` -- string that describes a color; this
|
|
457
|
+
can also be a list of 3-tuples or strings length 6 or 3, in which
|
|
458
|
+
case the faces (and oppositive faces) are colored
|
|
459
|
+
|
|
460
|
+
- ``opacity`` -- (default: 1) if less than 1 then is transparent
|
|
461
|
+
|
|
462
|
+
EXAMPLES: A plain Dodecahedron::
|
|
463
|
+
|
|
464
|
+
sage: dodecahedron()
|
|
465
|
+
Graphics3d Object
|
|
466
|
+
|
|
467
|
+
.. PLOT::
|
|
468
|
+
|
|
469
|
+
sphinx_plot(dodecahedron())
|
|
470
|
+
|
|
471
|
+
A translucent dodecahedron that contains a black sphere::
|
|
472
|
+
|
|
473
|
+
sage: G = dodecahedron(color='orange', opacity=0.8)
|
|
474
|
+
sage: G += sphere(size=0.5, color='black')
|
|
475
|
+
sage: G
|
|
476
|
+
Graphics3d Object
|
|
477
|
+
|
|
478
|
+
.. PLOT::
|
|
479
|
+
|
|
480
|
+
G = dodecahedron(color='orange', opacity=0.8)
|
|
481
|
+
G += sphere(size=0.5, color='black')
|
|
482
|
+
sphinx_plot(G)
|
|
483
|
+
|
|
484
|
+
CONSTRUCTION: This is how we construct a dodecahedron. We let one
|
|
485
|
+
point be `Q = (0,1,0)`.
|
|
486
|
+
|
|
487
|
+
Now there are three points spaced equally on a circle around the
|
|
488
|
+
north pole. The other requirement is that the angle between them be
|
|
489
|
+
the angle of a pentagon, namely `3\pi/5`. This is enough to
|
|
490
|
+
determine them. Placing one on the `xz`-plane we have.
|
|
491
|
+
|
|
492
|
+
`P_1 = \left(t, 0, \sqrt{1-t^2}\right)`
|
|
493
|
+
|
|
494
|
+
`P_2 = \left(-\frac{1}{2}t, \frac{\sqrt{3}}{2}t, \sqrt{1-t^2}\right)`
|
|
495
|
+
|
|
496
|
+
`P_3 = \left(-\frac{1}{2}t, \frac{\sqrt{3}}{2}t, \sqrt{1-t^2}\right)`
|
|
497
|
+
|
|
498
|
+
Solving
|
|
499
|
+
`\frac{(P_1-Q) \cdot (P_2-Q)}{|P_1-Q||P_2-Q|} = \cos(3\pi/5)`
|
|
500
|
+
we get `t = 2/3`.
|
|
501
|
+
|
|
502
|
+
Now we have 6 points `R_1, ..., R_6` to close the three
|
|
503
|
+
top pentagons. These can be found by mirroring `P_2` and
|
|
504
|
+
`P_3` by the `yz`-plane and rotating around the
|
|
505
|
+
`y`-axis by the angle `\theta` from `Q` to
|
|
506
|
+
`P_1`. Note that `\cos(\theta) = t = 2/3` and so
|
|
507
|
+
`\sin(\theta) = \sqrt{5}/3`. Rotation gives us the other
|
|
508
|
+
four.
|
|
509
|
+
|
|
510
|
+
Now we reflect through the origin for the bottom half.
|
|
511
|
+
|
|
512
|
+
AUTHORS:
|
|
513
|
+
|
|
514
|
+
- Robert Bradshaw, William Stein
|
|
515
|
+
"""
|
|
516
|
+
RR = RDF
|
|
517
|
+
one = RR.one()
|
|
518
|
+
sqrt3 = RR(3).sqrt()
|
|
519
|
+
sqrt5 = RR(5).sqrt()
|
|
520
|
+
R3 = RR**3
|
|
521
|
+
rot = matrix(RR, [[-one / 2, -sqrt3 / 2, 0],
|
|
522
|
+
[sqrt3 / 2, -one / 2, 0],
|
|
523
|
+
[0, 0, 1]])
|
|
524
|
+
rot2 = rot * rot
|
|
525
|
+
|
|
526
|
+
# The top
|
|
527
|
+
Q = R3([0, 0, 1])
|
|
528
|
+
# The first ring
|
|
529
|
+
P1 = R3([2*one/3, 0, sqrt5/3])
|
|
530
|
+
# The second ring
|
|
531
|
+
R1 = R3([sqrt5/3, 1/sqrt3, one/3])
|
|
532
|
+
R2 = R3([sqrt5/3, -1/sqrt3, one/3])
|
|
533
|
+
|
|
534
|
+
top = [Q, P1, rot*P1, rot2*P1, R1, rot*R2, rot*R1, rot2*R2, rot2*R1, R2]
|
|
535
|
+
point_list = top + [-p for p in reversed(top)]
|
|
536
|
+
|
|
537
|
+
top_faces = [[0,1,4,5,2],
|
|
538
|
+
[0,2,6,7,3],
|
|
539
|
+
[0,3,8,9,1],
|
|
540
|
+
[1,9,13,12,4],
|
|
541
|
+
[2,5,11,10,6],
|
|
542
|
+
[3,7,15,14,8]]
|
|
543
|
+
face_list = top_faces + [[19-p for p in reversed(f)] for f in top_faces]
|
|
544
|
+
|
|
545
|
+
if 'aspect_ratio' not in kwds:
|
|
546
|
+
kwds['aspect_ratio'] = [1,1,1]
|
|
547
|
+
return index_face_set(face_list, point_list, enclosed=True, center=center, size=size, **kwds)
|
|
548
|
+
|
|
549
|
+
# if style == 'vertices' or style == 'edges':
|
|
550
|
+
# from sage.plot.colors import rainbow
|
|
551
|
+
# colors = rainbow(len(vs), 'rgbtuple')
|
|
552
|
+
# #vertex_spheres = [Box(.05, .05, .05, color=color).translate(p) for p in vs]
|
|
553
|
+
# vertex_spheres = [Box(.05, .05, .05, color=c).translate(p) for p,c in zip(vs,colors)]
|
|
554
|
+
# faces = IndexFaceSet([[tuple(vs[i]) for i in f] for f in face_list])
|
|
555
|
+
# vertex_spheres += [faces.stickers(['red','yellow','blue','purple','black','orange'], .1, .1)] # [faces]
|
|
556
|
+
# return Graphics3dGroup(vertex_spheres)
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
@rename_keyword(alpha='opacity')
|
|
560
|
+
def icosahedron(center=(0, 0, 0), size=1, **kwds):
|
|
561
|
+
r"""
|
|
562
|
+
An icosahedron.
|
|
563
|
+
|
|
564
|
+
INPUT:
|
|
565
|
+
|
|
566
|
+
- ``center`` -- (default: (0, 0, 0))
|
|
567
|
+
|
|
568
|
+
- ``size`` -- (default: 1)
|
|
569
|
+
|
|
570
|
+
- ``color`` -- string that describes a color; this
|
|
571
|
+
can also be a list of 3-tuples or strings length 6 or 3, in which
|
|
572
|
+
case the faces (and oppositive faces) are colored
|
|
573
|
+
|
|
574
|
+
- ``opacity`` -- (default: 1) if less than 1 then is transparent
|
|
575
|
+
|
|
576
|
+
EXAMPLES::
|
|
577
|
+
|
|
578
|
+
sage: icosahedron()
|
|
579
|
+
Graphics3d Object
|
|
580
|
+
|
|
581
|
+
.. PLOT::
|
|
582
|
+
|
|
583
|
+
sphinx_plot(icosahedron())
|
|
584
|
+
|
|
585
|
+
Two icosahedra at different positions of different sizes. ::
|
|
586
|
+
|
|
587
|
+
sage: p = icosahedron((-1/2,0,1), color='orange')
|
|
588
|
+
sage: p += icosahedron((2,0,1), size=1/2, color='red', aspect_ratio=[1,1,1])
|
|
589
|
+
sage: p
|
|
590
|
+
Graphics3d Object
|
|
591
|
+
|
|
592
|
+
.. PLOT::
|
|
593
|
+
|
|
594
|
+
p = icosahedron((-1/2,0,1), color='orange')
|
|
595
|
+
p += icosahedron((2,0,1), size = 0.5, color='red', aspect_ratio=[1,1,1])
|
|
596
|
+
sphinx_plot(p)
|
|
597
|
+
"""
|
|
598
|
+
kwds['enclosed'] = True
|
|
599
|
+
if 'aspect_ratio' not in kwds:
|
|
600
|
+
kwds['aspect_ratio'] = [1, 1, 1]
|
|
601
|
+
return prep(dodecahedron().dual(**kwds), center, size, kwds)
|