aboutsummaryrefslogtreecommitdiffstats
path: root/video/qam.py
diff options
context:
space:
mode:
authorNaoki Pross <np@0hm.ch>2021-10-24 23:23:40 +0200
committerNaoki Pross <np@0hm.ch>2021-10-24 23:23:40 +0200
commitaf385473f8ab3c47024612635151bf0f98288f7d (patch)
tree412d14f42ace4a1cc279c08ed8814b900f78d7f2 /video/qam.py
parentCreate QPSK simulation without QT GUI (diff)
downloadFading-af385473f8ab3c47024612635151bf0f98288f7d.tar.gz
Fading-af385473f8ab3c47024612635151bf0f98288f7d.zip
Create TimeDependentComplexPlane tool for video
To draw a QAM signal we will need a way to plot a time dependent complex function. So I made a thing that is just a complex plane + a time axis.
Diffstat (limited to 'video/qam.py')
-rw-r--r--video/qam.py83
1 files changed, 78 insertions, 5 deletions
diff --git a/video/qam.py b/video/qam.py
index 917fdeb..88096e9 100644
--- a/video/qam.py
+++ b/video/qam.py
@@ -1,14 +1,87 @@
from manimlib import *
+from scipy import signal as sig
-class QamModulation(Scene):
+
+class TimeDependentComplexPlane(ComplexPlane):
CONFIG = {
- "camera_class": ThreeDCamera,
+ "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 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):
- circle = Circle()
- self.play(FadeIn(circle))
- self.wait(3)
+ cplane = TimeDependentComplexPlane()
+
+ self.play(ShowCreation(cplane))
+ 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(80, 90, 90))
+
+ # arrow = Arrow(
# open an interactive IPython shell here
self.embed()