summaryrefslogtreecommitdiffstats
path: root/manimgl/harmonics.py
blob: 0a1556608fea849f7a8bed15d8cacc1ccdaa0373 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
from manimlib import *

import numpy as np
from scipy.special import sph_harm

# configure style
config.background_color = '#202020'
# config.tex_template.add_to_preamble(
#     r"\usepackage[p,osf]{scholax}"
#     r"\usepackage{amsmath}"
#     r"\usepackage[scaled=1.075,ncf,vvarbb]{newtxmath}"
# )

class FourierOnS1(ThreeDScene):
    @staticmethod
    def harmonic_cos(m, n, theta, phi):
        # get only the cos() part
        r = np.real(sph_harm(m, n, theta, phi)) * 5 # Y_n^m 

        # coordinates transformation
        x = r * np.cos(theta) * np.sin(phi)
        y = r * np.sin(phi) * np.sin(theta)
        z = r * np.cos(phi)

        return [x, y, z]

    @staticmethod
    def harmonic_surf(m, n):
        surf = Surface(uv_func=lambda u, v: FourierOnS1.harmonic_cos(m, n, u, v),
                       u_range=[0, 2 * PI], v_range=[-PI, PI], 
                       color=GREY, resolution=(101, 101), shadow=0.1)

        surf.mesh = SurfaceMesh(surf)
        surf.mesh.set_stroke(BLACK, 1, opacity=0.7)

        return surf

    def construct(self):
        axes = ThreeDAxes(x_range=[-2, 2], y_range=[-2, 2], z_range=[-3, 3])
        self.add(axes)

        frame = self.camera.frame
        frame.set_euler_angles(theta=-30*DEGREES, phi=70*DEGREES)
        frame.add_updater(lambda m, dt: m.increment_theta(-0.1 * dt))

        last_surf = None
        last_label = None
        for n in range(0, 5):
            for m in range(0, n):
                surf = FourierOnS1.harmonic_surf(m, n)
                label = Tex(r"Y_{%d}^{%d}(\theta, \phi)" % (n, m))

                if last_surf is None:
                    self.play(ShowCreation(surf))
                    self.play(ShowCreation(surf.mesh, lag_ratio=0.01))
                else:
                    self.play(FadeOut(last_surf), FadeOut(last_surf.mesh))
                    self.play(ShowCreation(surf))
                    self.play(ShowCreation(surf.mesh, lag_ratio=0.01))

                if last_label is not None:
                    self.remove(last_label)

                label.to_corner(UL)

                last_surf = surf 
                last_label = label

                self.wait(3)

        self.wait(5)