summaryrefslogtreecommitdiff
path: root/FSF-2020/calculus-of-several-variables
diff options
context:
space:
mode:
Diffstat (limited to 'FSF-2020/calculus-of-several-variables')
-rw-r--r--FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file4_fs1.gifbin551048 -> 0 bytes
-rw-r--r--FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file4_fs1.py104
-rw-r--r--FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file5_fs2.gifbin629437 -> 0 bytes
-rw-r--r--FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file5_fs2.py28
-rw-r--r--FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file6_torsion_intuition.py119
5 files changed, 205 insertions, 46 deletions
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file4_fs1.gif b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file4_fs1.gif
deleted file mode 100644
index 6b4b438..0000000
--- a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file4_fs1.gif
+++ /dev/null
Binary files differ
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file4_fs1.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file4_fs1.py
index c719a1d..f3f5a9c 100644
--- a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file4_fs1.py
+++ b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file4_fs1.py
@@ -1,23 +1,91 @@
from manimlib.imports import *
-
-class fs1(ThreeDScene):
+class fs1(GraphScene):
+ CONFIG = {
+ "x_min": -2,
+ "x_max": 2,
+ "y_min": -6,
+ "y_max": 6,
+ "graph_origin": ORIGIN
+ }
def construct(self):
+ text = TextMobject(r'$\frac{dT}{ds} = \kappa N$ \\ $\frac{dT}{ds}$ gives the direction of N, \\ while $\kappa$ gives its magnitude.').scale(0.7).shift(3*UP + 3*LEFT)
+
+ self.setup_axes()
+ def curve_(x):
+ return x**3 - 2*x
+
+ def nm(x):
+ return abs(6 * x / ((9*(x**4) - 6*(x**2) + 5)**1.5))
+
+ figure = self.get_graph(curve_)
+
+
+ dot = Dot().rotate(PI/2)
+ alpha = ValueTracker(0)
+ t2_ = ValueTracker(-2)
+ t2 = t2_.get_value
+ t = alpha.get_value
+ vector_x = self.get_tangent_vector(t(),figure,scale=2)
+ vector_y = self.get_normal_vector(t(),figure,scale=2)
- self.set_camera_orientation(phi = 75*DEGREES, theta=45*DEGREES)
- dot1 = Dot(np.array([np.cos(-np.pi/3), np.sin(-np.pi/3), -0.4*np.pi/3]) + np.array([0,0.2,0]), radius = 0.16, color=RED)
- tgt1 = Arrow((0,0,0), (-2,-0.55,0), color = YELLOW).shift(dot1.get_center() + np.array([0.18,0.04,0]))
- nm1 = Arrow((0,0,0), (0.4,-2,0), color = BLUE).shift(dot1.get_center() + np.array([0,0.26,0])).shift(np.array([0.8,4.76,0])).rotate(-15*DEGREES).scale(0.8)
- bnm1 = Arrow((0,0,0), (0,2,0), color=GREEN_E).shift(2.1*RIGHT+2*DOWN)
- plane1 = Square(color = DARK_BROWN, fill_color = WHITE, fill_opacity=0.3).shift(dot1.get_center() + np.array([-0.4, -0.6, 0])).rotate(13*DEGREES).scale(1.2)
- point1 = VGroup(*[dot1, tgt1, plane1]).scale(0.8).shift(np.array([1,4.86,0])).rotate(-15*DEGREES)
- t = TextMobject(r'$T$', color = YELLOW).move_to(ORIGIN).shift(3.2*RIGHT + DOWN)
- n = TextMobject(r'$N$', color = BLUE).shift(DOWN + RIGHT)
- b = TextMobject(r'$B$', color = GREEN_E).next_to(bnm1, UP, buff = 0.1)
- text = VGroup(*[t, n, b])
- self.add_fixed_in_frame_mobjects(bnm1, text)
- self.play(FadeIn(point1), FadeIn(bnm1), FadeIn(text))
- self.wait()
- self.play(TransformFromCopy(tgt1, nm1, run_time = 2))
+ kappa = TextMobject(r'$\kappa = $').scale(0.7).shift(3*DOWN + 3*RIGHT)
+
+ t_text = always_redraw(
+ lambda: DecimalNumber(
+ nm(t2()),
+ color=WHITE,
+ ).scale(0.7).next_to(kappa)
+ ).scale(0.6)
+
+ self.play(
+ ShowCreation(figure),
+ GrowFromCenter(dot),
+ GrowArrow(vector_x),
+ GrowArrow(vector_y)
+ )
+ vector_x.add_updater(
+ lambda m: m.become(
+ self.get_tangent_vector(t(),figure,scale=2)
+ )
+ )
+ vector_y.add_updater(
+ lambda m: m.become(
+ self.get_normal_vector(t(),figure,scale=2)
+ )
+ )
+ dot.add_updater(lambda m: m.move_to(vector_x.get_start()))
+ circle = Circle(radius = 2, color = GREEN_SCREEN). shift(2.63*RIGHT + 2.8*UP)
+ dot2 = Dot(np.array([2, curve_(2), 0]), color = WHITE).shift(2*DOWN + 2.5*RIGHT)
+
+ self.add(vector_x, vector_y,dot, t_text, kappa, text)
+ self.play(t2_.set_value, 2, alpha.set_value, 1, run_time=18, rate_func=smooth)
+ self.play(FadeIn(dot2), FadeIn(circle))
self.wait(2)
- self.play(FadeOut(VGroup(*[bnm1, text, point1, nm1])))
+ self.play(FadeOut(VGroup(*[self.axes, dot2, figure, circle, text, kappa, t_text])))
+
+
+ def get_tangent_vector(self, proportion, curve, dx=0.001, scale=0.5):
+ coord_i = curve.point_from_proportion(proportion)
+ coord_f = curve.point_from_proportion(proportion + dx)
+ reference_line = Line(coord_i,coord_f)
+ unit_vector = reference_line.get_unit_vector() * 0.7
+ vector = Arrow(coord_i , coord_i + unit_vector, color = YELLOW, buff=0)
+ return vector
+
+ def get_normal_vector(self, proportion, curve, dx=0.001, scale=1):
+ t = proportion.copy()/6
+ coord_i = curve.point_from_proportion(proportion)
+ coord_f = curve.point_from_proportion(proportion + dx)
+ length = 6 * t / ((9*(t**4) - 6*(t**2) + 5)**1.5)
+ if coord_i[0] <= 0 and coord_i[0] > -0.5:
+ reference_line = Line(coord_i,coord_f).rotate(PI/2).set_width(0).scale(2)
+ elif coord_i[0] > 0 and (coord_i[0] < 0.5 or coord_i[0] > 2.7):
+ reference_line = Line(coord_i,coord_f).rotate(PI/2).set_width(0).scale(2)
+ elif coord_i[0] > 0:
+ reference_line = Line(coord_i,coord_f).rotate(PI/2).set_width(length).scale(2)
+ else:
+ reference_line = Line(coord_i,coord_f).rotate(-PI/2).set_width(length).scale(2)
+ unit_vector = reference_line.get_vector() * scale
+ vector = Arrow(coord_i , coord_i + unit_vector, color = RED_C, buff=0)
+ return vector
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file5_fs2.gif b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file5_fs2.gif
deleted file mode 100644
index ce367b6..0000000
--- a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file5_fs2.gif
+++ /dev/null
Binary files differ
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file5_fs2.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file5_fs2.py
deleted file mode 100644
index 0261fed..0000000
--- a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file5_fs2.py
+++ /dev/null
@@ -1,28 +0,0 @@
-from manimlib.imports import *
-
-class fs1(ThreeDScene):
- def construct(self):
-
-
- self.set_camera_orientation(phi = 75*DEGREES, theta=45*DEGREES)
- dot1 = Dot(np.array([np.cos(-np.pi/3), np.sin(-np.pi/3), -0.4*np.pi/3]) + np.array([0,0.2,0]), radius = 0.16, color=RED)
- tgt1 = Arrow((0,0,0), (-2,-0.55,0), color = YELLOW).shift(dot1.get_center() + np.array([0.18,0.04,0]))
- nm1 = Arrow((0,0,0), (0.4,-2,0), color = BLUE).shift(dot1.get_center() + np.array([0,0.26,0])).shift(np.array([0.8,4.76,0])).rotate(-15*DEGREES).scale(0.8)
- bnm1 = Arrow((0,0,0), (0,2,0), color=GREEN_E).shift(2.1*RIGHT+2*DOWN)
-
- bnms = Line((0,0,0), (0,0,1.6), color = GREEN_E).shift(np.array([3.1,5.2,0])).scale(0.6)
- bnmsa = ArrowTip(color = GREEN_E).next_to(bnms, np.array([0,0,1]), buff = 0).rotate(45*DEGREES)
- bns = VGroup(*[bnms, bnmsa])
-
- plane1 = Square(color = DARK_BROWN, fill_color = WHITE, fill_opacity=0.3).shift(dot1.get_center() + np.array([-0.4, -0.6, 0])).rotate(13*DEGREES).scale(1.2)
- point1 = VGroup(*[dot1, tgt1, plane1]).scale(0.8).shift(np.array([1,4.86,0])).rotate(-15*DEGREES)
- t = TextMobject(r'$T$', color = YELLOW).move_to(ORIGIN).shift(3.2*RIGHT + DOWN)
- n = TextMobject(r'$N$', color = BLUE).shift(DOWN + RIGHT)
- b = TextMobject(r'$B$', color = GREEN_E).next_to(bnm1, UP, buff = 0.1)
- text = VGroup(*[t, n, b])
- self.add_fixed_in_frame_mobjects(bnm1, text)
- self.play(FadeIn(point1), FadeIn(text), FadeIn(bnm1))
- self.wait()
- self.play(TransformFromCopy(bnms, nm1, run_time = 3))
- self.wait(2)
- self.play(FadeOut(VGroup(*[bnms, text, point1, nm1, bnm1])))
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file6_torsion_intuition.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file6_torsion_intuition.py
new file mode 100644
index 0000000..31b9a85
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file6_torsion_intuition.py
@@ -0,0 +1,119 @@
+from manimlib.imports import *
+
+class t(SpecialThreeDScene):
+ CONFIG = {
+ "axes_config": {
+ "x_min": -5,
+ "x_max": 5,
+ "y_min": -5,
+ "y_max": 5,
+ "z_min": -4,
+ "z_max": 4,
+ "x_axis_config": {
+ "tick_frequency": 100,
+ },
+ "y_axis_config": {
+ "tick_frequency": 100,
+ },
+ "z_axis_config": {
+ "tick_frequency": 100,
+ },
+ "num_axis_pieces": 1,
+ }
+ }
+ def construct(self):
+
+ text = TextMobject(r'Torsion can be intuitively \\ thought of as the measure \\ of "twisting" of a curve.').scale(0.7).shift(2.5*UP + 4.2*LEFT)
+
+
+ dot = Dot().rotate(PI/2)
+ f1 = ParametricFunction(
+ lambda t: np.array([
+ 2*np.sin(TAU*t),
+ 2*np.cos(TAU*t),
+ 2*t
+ ]), t_min = -2, t_max = 2, color = BLUE
+ ).scale(0.5)
+ d1 = Dot(color = RED).next_to(f1.get_center(), 2*DOWN + LEFT, buff = 0).shift(1.2*UP + 2.4*RIGHT)
+ t1 = self.get_torsion(2, 0.174)
+ t1 = "{:.2f}".format(t1)
+ t1 = TextMobject(fr'At the given point, $\tau = {t1}$').shift(3.5*DOWN).scale(0.7)
+
+ f2 = ParametricFunction(
+ lambda t: np.array([
+ 3*np.sin(TAU*t),
+ 3*np.cos(TAU*t),
+ 2*t
+ ]), t_min = -2, t_max = 2, color = BLUE
+ ).scale(0.5)
+ d2 = Dot(color = RED).next_to(f2.get_center(), 2*DOWN + LEFT, buff = 0).shift(1.2*UP + 2.95*RIGHT)
+ t2 = self.get_torsion(3, 0.1765)
+ t2 = "{:.2f}".format(t2)
+ t2 = TextMobject(fr'At the given point, $\tau = {t2}$').shift(3.5*DOWN).scale(0.7)
+
+ f3 = ParametricFunction(
+ lambda t: np.array([
+ 4*np.sin(TAU*t),
+ 4*np.cos(TAU*t),
+ 2*t
+ ]), t_min = -2, t_max = 2, color = BLUE
+ ).scale(0.5)
+ d3 = Dot(color = RED).next_to(f3.get_center(), 2*DOWN + LEFT, buff = 0).shift(1.2*UP + 3.45*RIGHT)
+ t3 = self.get_torsion(4, 0.179)
+ t3 = "{:.2f}".format(t3)
+ t3 = TextMobject(fr'At the given point, $\tau = {t3}$').shift(3.5*DOWN).scale(0.7)
+
+ f4 = ParametricFunction(
+ lambda t: np.array([
+ 1.5*np.sin(TAU*t),
+ 1.5*np.cos(TAU*t),
+ 2*t
+ ]), t_min = -2, t_max = 2, color = BLUE
+ ).scale(0.5)
+ d4 = Dot(color = RED).next_to(f4.get_center(), 2*DOWN + LEFT, buff = 0).shift(1.215*UP + 2.128*RIGHT)
+ t4 = self.get_torsion(1.5, 0.173)
+ t4 = "{:.2f}".format(t4)
+ t4 = TextMobject(fr'At the given point, $\tau = {t4}$').shift(3.5*DOWN).scale(0.7)
+
+ f5 = ParametricFunction(
+ lambda t: np.array([
+ np.sin(TAU*t),
+ np.cos(TAU*t),
+ 2*t
+ ]), t_min = -2, t_max = 2, color = BLUE
+ ).scale(0.5)
+
+ d5 = Dot(color = RED).next_to(f5.get_center(), 2*DOWN + LEFT, buff = 0).shift(1.3*UP + 1.858*RIGHT)
+ t5 = self.get_torsion(1, 0.17)
+ t5 = "{:.2f}".format(t5)
+ t5 = TextMobject(fr'At the given point, $\tau = {t5}$').shift(3.5*DOWN).scale(0.7)
+
+ axes = ThreeDAxes(**self.axes_config)
+ self.set_camera_orientation(phi = 60*DEGREES, theta=45*DEGREES)
+ self.add_fixed_in_frame_mobjects(t1, text)
+ self.play(FadeIn(VGroup(*[f1, d1, t1, axes, text])))
+ self.wait(2)
+ self.add_fixed_in_frame_mobjects(t2)
+ self.play(ReplacementTransform(d1, d2), ReplacementTransform(f1, f2), ReplacementTransform(t1, t2))
+ self.wait(2)
+ self.add_fixed_in_frame_mobjects(t3)
+ self.play(ReplacementTransform(d2, d3), ReplacementTransform(f2, f3), ReplacementTransform(t2, t3))
+ self.wait(2)
+ self.add_fixed_in_frame_mobjects(t4)
+ self.play(ReplacementTransform(d3, d4), ReplacementTransform(f3, f4), ReplacementTransform(t3, t4))
+ self.wait(2)
+ self.add_fixed_in_frame_mobjects(t5)
+ self.play(ReplacementTransform(d4, d5), ReplacementTransform(f4, f5), ReplacementTransform(t4, t5))
+ self.wait(2)
+ self.play(FadeOut(VGroup(*[d5, f5, t5, text, axes])))
+
+ def get_torsion(self, a, t):
+ rprime = np.array([a*np.cos(t), -a*np.sin(t), 2])
+ T = rprime / np.sqrt(np.dot(rprime, rprime))
+ rpp = np.array([-a*np.sin(t), -a*np.cos(t), 0])
+ n = rpp / np.dot(rpp, rpp)
+ b = np.cross(T, n)
+ dbdt = np.array([-2*np.sin(t), -2*np.cos(t), 0])
+ tor = np.dot(dbdt, n)
+
+ return tor