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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
from manimlib import *
from scipy import signal as sig
class TimeDependentComplexPlane(ComplexPlane):
CONFIG = {
"dimension": 3,
"t_range": np.array([0., 5., 1.]),
"t_axis_config": {
"include_ticks": True,
},
"background_line_style": {
"stroke_color": GREY_D,
},
"depth": 8,
}
def __init__(self, **kwargs):
ComplexPlane.__init__(self, **kwargs)
t_axis = self.create_axis(self.t_range, self.t_axis_config, self.depth)
t_axis.rotate(-PI / 2, UP, about_point=ORIGIN)
t_axis.shift(self.n2p(0))
self.t_axis = t_axis
self.add(t_axis)
self.axes.add(t_axis)
def number_to_point(self, number, time=0):
return self.coords_to_point(number.real, number.imag, time)
def point_to_number(self, point, time=0):
return point[0] + 1j * point[1]
def n2p(self, number, time=0):
return self.number_to_point(number, time)
def get_t_axis(self):
return self.axes[2]
def get_graph(self, function, axis, t_range=None, **kwargs):
# sample range
s_range = np.array(self.t_range, dtype=float)
if t_range is not None:
s_range[:len(t_range)] = t_range
if t_range is None or len(t_range) < 3:
s_range[2] /= self.num_sampled_graph_points_per_tick
graph = ParametricCurve(
lambda t: self.t_axis.number_to_point(t) + axis.number_to_point(function(t)),
t_range=s_range,
**kwargs
)
graph.underlying_function = function
graph.t_range = t_range
return graph
def get_inphase_graph(self, function, **kwargs):
return self.get_graph(function, self.get_x_axis(), **kwargs)
def get_quadrature_graph(self, function, **kwargs):
return self.get_graph(function, self.get_y_axis(), **kwargs)
class QamModulation(Scene):
CONFIG = {}
def construct(self):
self.camera.frame.reorient(0, 0, 0)
cplane = TimeDependentComplexPlane()
self.play(ShowCreation(cplane))
dot = Dot(cplane.n2p(1 + 2j))
number = DecimalNumber()
number.add_updater(lambda m: m.next_to(dot, RIGHT))
def update_nums(m):
x, y, z = dot.get_center()
num = cplane.p2n((x,y))
m.set_value(num)
number.add_updater(update_nums)
self.play(ShowCreation(dot), ShowCreation(number))
self.play(dot.animate.move_to(cplane.n2p(-5 + 3j)), run_time=2)
self.play(dot.animate.move_to(cplane.n2p(-1 - 3j)), run_time=2)
self.play(dot.animate.move_to(cplane.n2p(4 - 3j)))
self.wait(1)
# Get out and show time dependence
self.play(self.camera.frame.animate.move_to(2 * OUT))
graph_y = cplane.get_inphase_graph(lambda t: -2 * np.cos(2 * t), color=RED)
graph_x = cplane.get_quadrature_graph(lambda t: 1 * sig.square(4 * t), color=BLUE)
self.play(self.camera.frame.animate.reorient(-90, 90, 90))
self.play(ShowCreation(graph_x))
self.play(self.camera.frame.animate.reorient(0, 90, 90))
self.play(ShowCreation(graph_y))
self.play(self.camera.frame.animate.reorient(-100, 90, 90))
# arrow = Arrow(
# open an interactive IPython shell here
# self.embed()
|