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,268 @@
1
+ # sage_setup: distribution = sagemath-plot
2
+ """
3
+ Transformations
4
+ """
5
+
6
+ # ***************************************************************************
7
+ # Copyright (C) 2007 Robert Bradshaw <robertwb@math.washington.edu>
8
+ #
9
+ # This program is free software: you can redistribute it and/or modify
10
+ # it under the terms of the GNU General Public License as published by
11
+ # the Free Software Foundation, either version 2 of the License, or
12
+ # (at your option) any later version.
13
+ # https://www.gnu.org/licenses/
14
+ # ***************************************************************************
15
+
16
+ from libc.math cimport sin, cos, sqrt
17
+
18
+ include "point_c.pxi"
19
+
20
+ from sage.rings.real_double import RDF
21
+
22
+ from sage.matrix.constructor import matrix
23
+ from sage.modules.free_module_element import vector
24
+
25
+ pi = RDF.pi()
26
+
27
+
28
+ cdef class Transformation:
29
+ def __init__(self, scale=(1,1,1),
30
+ rot=None,
31
+ trans=[0,0,0],
32
+ m=None):
33
+
34
+ if scale is None:
35
+ scale = (1,1,1)
36
+ if trans is None:
37
+ trans = [0,0,0]
38
+
39
+ # TODO: determine for sure if x3d does scale or rotation first
40
+ if m is not None:
41
+ self.matrix = m
42
+
43
+ else:
44
+ m = matrix(RDF, 3, 3,
45
+ [scale[0], 0, 0, 0, scale[1], 0, 0, 0, scale[2]])
46
+
47
+ if rot is not None:
48
+ # rotate about v by theta
49
+ vx, vy, vz, theta = rot
50
+ m *= rotate_arbitrary((vx, vy, vz), theta)
51
+
52
+ self.matrix = m.augment(matrix(RDF, 3, 1, list(trans))) \
53
+ .stack(matrix(RDF, 1, 4, [0,0,0,1]))
54
+
55
+ # this raw data is used for optimized transformations
56
+ m_data = self.matrix.list()
57
+ cdef int i
58
+ for i in range(12):
59
+ self._matrix_data[i] = m_data[i]
60
+
61
+ def get_matrix(self):
62
+ return self.matrix.__copy__()
63
+
64
+ def is_skew(self, eps=1e-5):
65
+ dx, dy, dz = self.matrix[0:3, 0:3].columns()
66
+ return abs(dx.dot_product(dy)) + abs(dx.dot_product(dz)) + abs(dy.dot_product(dz)) > eps
67
+
68
+ def is_uniform(self, eps=1e-5):
69
+ cols = self.matrix[0:3, 0:3].columns()
70
+ lens = [col.dot_product(col) for col in cols]
71
+ return abs(lens[0] - lens[1]) + abs(lens[0] - lens[2]) < eps
72
+
73
+ def is_uniform_on(self, basis, eps=1e-5):
74
+ basis = [vector(RDF, self.transform_vector(b)) for b in basis]
75
+ a = basis.pop()
76
+ len_a = a.dot_product(a)
77
+ return max([abs(len_a - b.dot_product(b)) for b in basis]) < eps
78
+
79
+ cpdef transform_point(self, x):
80
+ cdef point_c res, P
81
+ P.x, P.y, P.z = x
82
+ point_c_transform(&res, self._matrix_data, P)
83
+ return res.x, res.y, res.z
84
+
85
+ cpdef transform_vector(self, v):
86
+ cdef point_c res, P
87
+ P.x, P.y, P.z = v
88
+ point_c_stretch(&res, self._matrix_data, P)
89
+ return res.x, res.y, res.z
90
+
91
+ cpdef transform_bounding_box(self, box):
92
+ cdef point_c lower, upper, res, temp
93
+ cdef point_c bounds[2]
94
+ bounds[0].x, bounds[0].y, bounds[0].z = box[0]
95
+ bounds[1].x, bounds[1].y, bounds[1].z = box[1]
96
+ point_c_transform(&lower, self._matrix_data, bounds[0])
97
+ point_c_transform(&upper, self._matrix_data, bounds[0])
98
+ cdef int i
99
+ for i in range(1, 8):
100
+ temp.x = bounds[ i & 1 ].x
101
+ temp.y = bounds[(i & 2) >> 1].y
102
+ temp.z = bounds[(i & 4) >> 2].z
103
+ point_c_transform(&res, self._matrix_data, temp)
104
+ point_c_lower_bound(&lower, lower, res)
105
+ point_c_upper_bound(&upper, upper, res)
106
+ return (lower.x, lower.y, lower.z), (upper.x, upper.y, upper.z)
107
+
108
+ cdef void transform_point_c(self, point_c* res, point_c P) noexcept:
109
+ point_c_transform(res, self._matrix_data, P)
110
+
111
+ cdef void transform_vector_c(self, point_c* res, point_c P) noexcept:
112
+ point_c_stretch(res, self._matrix_data, P)
113
+
114
+ def __mul__(Transformation self, Transformation other):
115
+ return Transformation(m = self.matrix * other.matrix)
116
+
117
+ def __invert__(Transformation self):
118
+ return Transformation(m=~self.matrix)
119
+
120
+ def __call__(self, p):
121
+ return self.transform_point(p)
122
+
123
+ def max_scale(self):
124
+ if self._svd is None:
125
+ self._svd = self.matrix[0:3, 0:3].SVD()
126
+ return self._svd[1][0,0]
127
+
128
+ def avg_scale(self):
129
+ if self._svd is None:
130
+ self._svd = self.matrix[0:3, 0:3].SVD()
131
+ return (self._svd[1][0,0] * self._svd[1][1,1] * self._svd[1][2,2]) ** (1/3.0)
132
+
133
+
134
+ def rotate_arbitrary(v, double theta):
135
+ """
136
+ Return a matrix that rotates the coordinate space about
137
+ the axis v by the angle ``theta``.
138
+
139
+ INPUT:
140
+
141
+ - ``theta`` -- real number, the angle
142
+
143
+ EXAMPLES::
144
+
145
+ sage: from sage.plot.plot3d.transform import rotate_arbitrary
146
+
147
+ Try rotating about the axes::
148
+
149
+ sage: rotate_arbitrary((1,0,0), 1)
150
+ [ 1.0 0.0 0.0]
151
+ [ 0.0 0.5403023058681398 0.8414709848078965]
152
+ [ 0.0 -0.8414709848078965 0.5403023058681398]
153
+ sage: rotate_arbitrary((0,1,0), 1)
154
+ [ 0.5403023058681398 0.0 -0.8414709848078965]
155
+ [ 0.0 1.0 0.0]
156
+ [ 0.8414709848078965 0.0 0.5403023058681398]
157
+ sage: rotate_arbitrary((0,0,1), 1)
158
+ [ 0.5403023058681398 0.8414709848078965 0.0]
159
+ [-0.8414709848078965 0.5403023058681398 0.0]
160
+ [ 0.0 0.0 1.0]
161
+
162
+ These next two should be the same (up to floating-point errors)::
163
+
164
+ sage: rotate_arbitrary((1,1,1), 1) # rel tol 1e-15
165
+ [ 0.6935348705787598 0.6390560643047186 -0.33259093488347846]
166
+ [-0.33259093488347846 0.6935348705787598 0.6390560643047186]
167
+ [ 0.6390560643047186 -0.3325909348834784 0.6935348705787598]
168
+ sage: rotate_arbitrary((1,1,1), -1)^(-1) # rel tol 1e-15
169
+ [ 0.6935348705787598 0.6390560643047186 -0.33259093488347846]
170
+ [-0.33259093488347846 0.6935348705787598 0.6390560643047186]
171
+ [ 0.6390560643047185 -0.33259093488347835 0.6935348705787598]
172
+
173
+ Make sure it does the right thing...::
174
+
175
+ sage: rotate_arbitrary((1,2,3), -1).det()
176
+ 1.0000000000000002
177
+ sage: rotate_arbitrary((1,1,1), 2*pi/3) * vector(RDF, (1,2,3)) # rel tol 2e-15 # needs sage.symbolic
178
+ (1.9999999999999996, 2.9999999999999996, 0.9999999999999999)
179
+ sage: rotate_arbitrary((1,2,3), 5) * vector(RDF, (1,2,3)) # rel tol 2e-15
180
+ (1.0000000000000002, 2.0, 3.000000000000001)
181
+ sage: rotate_arbitrary((1,1,1), pi/7)^7 # rel tol 2e-15 # needs sage.symbolic
182
+ [-0.33333333333333337 0.6666666666666671 0.6666666666666665]
183
+ [ 0.6666666666666665 -0.33333333333333337 0.6666666666666671]
184
+ [ 0.6666666666666671 0.6666666666666667 -0.33333333333333326]
185
+
186
+ AUTHORS:
187
+
188
+ - Robert Bradshaw
189
+
190
+ ALGORITHM:
191
+
192
+ There is a formula. Where did it come from? Lets take
193
+ a quick jaunt into Sage's calculus package...
194
+
195
+ Setup some variables::
196
+
197
+ sage: vx,vy,vz,theta = var('x y z theta') # needs sage.symbolic
198
+
199
+ Symbolic rotation matrices about X and Y axis::
200
+
201
+ sage: def rotX(theta): return matrix(SR, 3, 3, [1, 0, 0, 0, cos(theta), -sin(theta), 0, sin(theta), cos(theta)])
202
+ sage: def rotZ(theta): return matrix(SR, 3, 3, [cos(theta), -sin(theta), 0, sin(theta), cos(theta), 0, 0, 0, 1])
203
+
204
+ Normalizing `y` so that `|v|=1`. Perhaps there is a better
205
+ way to tell Maxima that `x^2+y^2+z^2=1` which would make for
206
+ a much cleaner calculation::
207
+
208
+ sage: vy = sqrt(1-vx^2-vz^2) # needs sage.symbolic
209
+
210
+ Now we rotate about the `x`-axis so `v` is in the `xy`-plane::
211
+
212
+ sage: t = arctan(vy/vz)+pi/2 # needs sage.symbolic
213
+ sage: m = rotX(t) # needs sage.symbolic
214
+ sage: new_y = vy*cos(t) - vz*sin(t) # needs sage.symbolic
215
+
216
+ And rotate about the `z` axis so `v` lies on the `x` axis::
217
+
218
+ sage: s = arctan(vx/new_y) + pi/2 # needs sage.symbolic
219
+ sage: m = rotZ(s) * m # needs sage.symbolic
220
+
221
+ Rotating about `v` in our old system is the same as rotating
222
+ about the `x`-axis in the new::
223
+
224
+ sage: m = rotX(theta) * m # needs sage.symbolic
225
+
226
+ Do some simplifying here to avoid blow-up::
227
+
228
+ sage: m = m.simplify_rational() # needs sage.symbolic
229
+
230
+ Now go back to the original coordinate system::
231
+
232
+ sage: m = rotZ(-s) * m # needs sage.symbolic
233
+ sage: m = rotX(-t) * m # needs sage.symbolic
234
+
235
+ And simplify every single entry (which is more effective that simplify
236
+ the whole matrix like above)::
237
+
238
+ sage: m.parent()([x.simplify_full() for x in m._list()]) # random # long time, needs sage.symbolic
239
+ [ -(cos(theta) - 1)*x^2 + cos(theta) -(cos(theta) - 1)*sqrt(-x^2 - z^2 + 1)*x + sin(theta)*abs(z) -((cos(theta) - 1)*x*z^2 + sqrt(-x^2 - z^2 + 1)*sin(theta)*abs(z))/z]
240
+ [ -(cos(theta) - 1)*sqrt(-x^2 - z^2 + 1)*x - sin(theta)*abs(z) (cos(theta) - 1)*x^2 + (cos(theta) - 1)*z^2 + 1 -((cos(theta) - 1)*sqrt(-x^2 - z^2 + 1)*z*abs(z) - x*z*sin(theta))/abs(z)]
241
+ [ -((cos(theta) - 1)*x*z^2 - sqrt(-x^2 - z^2 + 1)*sin(theta)*abs(z))/z -((cos(theta) - 1)*sqrt(-x^2 - z^2 + 1)*z*abs(z) + x*z*sin(theta))/abs(z) -(cos(theta) - 1)*z^2 + cos(theta)]
242
+
243
+ Re-expressing some entries in terms of y and resolving the absolute
244
+ values introduced by eliminating y, we get the desired result.
245
+ """
246
+ cdef double x,y,z, len_v
247
+ x,y,z = v
248
+ len_v = sqrt(x*x+y*y+z*z)
249
+ # normalize for an easier formula
250
+ x /= len_v
251
+ y /= len_v
252
+ z /= len_v
253
+ cdef double cos_t = cos(theta), sin_t = sin(theta)
254
+
255
+ entries = [
256
+ (1 - cos_t)*x*x + cos_t,
257
+ sin_t*z - (cos_t - 1)*x*y,
258
+ -sin_t*y + (1 - cos_t)*x*z,
259
+
260
+ -sin_t*z + (1 - cos_t)*x*y,
261
+ (1 - cos_t)*y*y + cos_t,
262
+ sin_t*x - (cos_t - 1)*z*y,
263
+
264
+ sin_t*y - (cos_t - 1)*x*z,
265
+ -(cos_t - 1)*z*y - sin_t*x,
266
+ (1 - cos_t)*z*z + cos_t ]
267
+
268
+ return matrix(RDF, 3, 3, entries)