diff options
Diffstat (limited to 'FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae')
8 files changed, 591 insertions, 56 deletions
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file3_tnb_frame_manim.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file3_tnb_frame_manim.py index 176cac5..091c1e2 100644 --- a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file3_tnb_frame_manim.py +++ b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file3_tnb_frame_manim.py @@ -11,6 +11,9 @@ class tnb(ThreeDScene): text = VGroup(*[t,n,b,frame]).move_to(ORIGIN).shift(3*UP) + c1 = TextMobject(r'$r(t) = \left\langle\cos{t}, \sin{t}, 0.4t\right\rangle\quad r\prime (t) =\left\langle -\sin{t}, \cos{t}, 0.4\right\rangle$').next_to(text, DOWN, buff = 0.1).scale(0.7) + + helix1 = ParametricFunction( lambda t: np.array([ np.cos(TAU*t), @@ -53,6 +56,95 @@ class tnb(ThreeDScene): helix_dot = Dot(radius = 0.16, color = RED) + t_tracker = ValueTracker(-2*np.pi/3) + t=t_tracker.get_value + + # t_label = TexMobject( + # "t = ",color=WHITE + # ).next_to(helix1,DOWN, buff=0.2).scale(0.6) + + cval1 = TextMobject(r'r(').next_to(c1, DOWN+16.5*LEFT, buff = 0.1).scale(0.7) + + t_text = always_redraw( + lambda: DecimalNumber( + t(), + color=WHITE, + ).next_to(cval1, RIGHT, buff=0.05).scale(0.7) + ).scale(0.6) + + + cval2 = always_redraw( + lambda: TextMobject(r') = $\left\langle$').scale(0.7).next_to(t_text, RIGHT, buff = 0.05) + ) + + cos = always_redraw( + lambda: DecimalNumber( + np.cos(t()), + color=WHITE, + ).next_to(cval2, RIGHT, buff=0.1).scale(0.7) + ).scale(0.6) + + sin = always_redraw( + lambda: DecimalNumber( + np.sin(t()), + color=WHITE, + ).next_to(cos, RIGHT, buff=0.1).scale(0.7) + ).scale(0.6) + + zpart = always_redraw( + lambda: DecimalNumber( + 0.4* t(), + color=WHITE, + ).next_to(sin, RIGHT, buff=0.1).scale(0.7) + ).scale(0.6) + + cvalend = always_redraw( + lambda: TextMobject(r' $\right\rangle$').next_to(zpart, RIGHT, buff = 0.2).scale(0.7) + ).scale(0.6) + + + valgroup = VGroup(*[cval1, cval2,cos,sin,zpart, cvalend]) + + rp1 = always_redraw( + lambda: TextMobject(r'$r\prime ($').scale(0.7).next_to(cvalend, RIGHT, buff = 0.6) + ) + + t_text2 = always_redraw( + lambda: DecimalNumber( + t(), + color=WHITE, + ).next_to(rp1, RIGHT, buff=0.05).scale(0.7) + ).scale(0.6) + + rp2 = always_redraw( + lambda: TextMobject(r') = $\left\langle$').scale(0.7).next_to(t_text2, RIGHT, buff = 0.05) + ) + + rps = always_redraw( + lambda: DecimalNumber( + -np.sin(t()), + color=WHITE, + ).next_to(rp2, RIGHT, buff=0.1).scale(0.7) + ).scale(0.6) + + + rpc = always_redraw( + lambda: DecimalNumber( + np.cos(t()), + color=WHITE, + ).next_to(rps, RIGHT, buff=0.1).scale(0.7) + ).scale(0.6) + + + const = always_redraw( + lambda: TextMobject(r'0.4 $\right\rangle$').next_to(rpc, RIGHT, buff = 0.2).scale(0.7) + ).scale(0.6).shift(0.1*DOWN) + + val2group = VGroup(*[rp1, rp2, rps, rpc, const]) + + #group = VGroup(t_text, t_text2).scale(1.5).move_to(ORIGIN).shift(3.7*DOWN) + + dot0 = Dot(np.array([np.cos(-2*np.pi/3), np.sin(-2*np.pi/3), -0.8*np.pi/3]), radius = 0.16, color=RED).shift(np.array([4.65,0,-0.8])) tgt0 = Arrow((0,0,0), (1,2,0), color = YELLOW).shift(dot0.get_center() - np.array([0.04,0.2,0])) nm0 = Arrow((0,0,0), (-2,1,0), color = BLUE).shift(dot0.get_center() + np.array([0.3,0,0])) @@ -75,20 +167,20 @@ class tnb(ThreeDScene): point2 = VGroup(*[dot2, tgt2, nm2, bnm2, plane2]) helix = VGroup(*[helix1, helix2, helix3, helix4, helix5]) - self.add_fixed_in_frame_mobjects(text) - self.play(FadeIn(helix), FadeIn(text)) + self.add_fixed_in_frame_mobjects(text, c1) + self.play(FadeIn(helix), FadeIn(text), FadeIn(c1)) self.play(ApplyMethod(helix.scale, 4)) - self.add_fixed_in_frame_mobjects(bnm0) - self.play(FadeIn(point0)) - self.play(ApplyMethod(point0.set_color, GRAY, opacity = 0.1), MoveAlongPath(helix_dot, helix1, run_time=5)) + self.add_fixed_in_frame_mobjects(bnm0, valgroup, val2group, t_text, t_text2) + self.play(FadeIn(point0), FadeIn(t_text), FadeIn(t_text2), FadeIn(valgroup), FadeIn(val2group)) + self.play(ApplyMethod(point0.set_color, GRAY, opacity = 0.1, run_time = 0.5), MoveAlongPath(helix_dot, helix1, run_time=5), t_tracker.set_value,-1.638*np.pi/3, rate_func=linear, run_time=5) self.add_fixed_in_frame_mobjects(bnm1) self.play(FadeIn(point1)) - self.play(ApplyMethod(point1.set_color, GRAY, opacity = 0.1), ApplyMethod(bnm1.set_color, GRAY, opacity = 0.1), MoveAlongPath(helix_dot, helix2, run_time = 5)) + self.play(ApplyMethod(point1.set_color, GRAY, opacity = 0.1, run_time = 0.5), ApplyMethod(bnm1.set_color, GRAY, opacity = 0.1, run_time = 0.5), MoveAlongPath(helix_dot, helix2, run_time = 5), t_tracker.set_value,-1.33*np.pi/3, rate_func=linear, run_time=5) self.add_fixed_in_frame_mobjects(bnm2) self.play(FadeIn(point2)) - self.play(ApplyMethod(point2.set_color, GRAY, opacity = 0.1), MoveAlongPath(helix_dot, helix3, run_time=5)) + self.play(ApplyMethod(point2.set_color, GRAY, opacity = 0.1, run_time = 0.5), MoveAlongPath(helix_dot, helix3, run_time=5), t_tracker.set_value,-np.pi/3, rate_func=linear, run_time=5) dot3 = Dot(np.array([np.cos(-np.pi/3), np.sin(-np.pi/3), -0.4*np.pi/3]) + np.array([3.3,-0.25,0]), radius = 0.16, color=RED) tgt3 = Arrow((0,0,0), (0,2,0), color = YELLOW).shift(helix_dot.get_center() - np.array([-0.05,0.2,0])) @@ -113,14 +205,14 @@ class tnb(ThreeDScene): self.add_fixed_in_frame_mobjects(bnm3) self.play(FadeIn(point3)) - self.play(ApplyMethod(point3.set_color, GRAY, opacity = 0.1), MoveAlongPath(helix_dot, helix4, run_time=5)) + self.play(ApplyMethod(point3.set_color, GRAY, opacity = 0.1, run_time = 0.5), MoveAlongPath(helix_dot, helix4, run_time=5), t_tracker.set_value,-1.3*np.pi/6, rate_func=linear, run_time=5) self.add_fixed_in_frame_mobjects(bnm4) self.play(FadeIn(point4)) - self.play(ApplyMethod(point4.set_color, GRAY, opacity = 0.1), MoveAlongPath(helix_dot, helix5, run_time=5)) + self.play(ApplyMethod(point4.set_color, GRAY, opacity = 0.1, run_time = 0.5), MoveAlongPath(helix_dot, helix5, run_time=5), t_tracker.set_value,0, rate_func=linear, run_time=5) self.add_fixed_in_frame_mobjects(bnm5) self.play(FadeIn(point5)) self.wait(2) - self.play(FadeOut(VGroup(*[text, helix, bnm1, point0, point1, point2, point3, point4, point5, helix_dot]))) + self.play(FadeOut(VGroup(*[valgroup, val2group, t_text, t_text2, c1, text, helix, bnm1, point0, point1, point2, point3, point4, point5, helix_dot]))) 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 Binary files differdeleted 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 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 Binary files differdeleted 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 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/file5_torsion_intuition.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file5_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/file5_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 diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file6_fs2.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file6_fs2.py new file mode 100644 index 0000000..0c74685 --- /dev/null +++ b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file6_fs2.py @@ -0,0 +1,90 @@ +from manimlib.imports import * + +class fs2(SpecialThreeDScene): + CONFIG = { + "x_min": -2, + "x_max": 2, + "y_min": -6, + "y_max": 6, + "graph_origin": ORIGIN + } + def construct(self): + axes = ThreeDAxes() + # text = TextMobject(r'$\frac{dB}{ds} = -\tau N$ \\ $\frac{dB}{ds}$ gives the direction of N, \\ while $\tau$ gives its magnitude.').scale(0.7).shift(3*UP + 3*LEFT) + self.set_camera_orientation(phi = 75*DEGREES, theta=135*DEGREES) + # self.move_camera(distance=0) + + # rprime = np.array([2*np.cos(t), -np.sin(t) - (2*np.sin(2*t)), 0]) + # t = rprime / np.sqrt(np.dot(rprime, rprime)) + # rpp = np.array([-2*np.sin(t), -np.cos(t) - (4*np.cos(2*t)), 0]) + # n = rpp / np.dot(rpp, rpp) + # b = np.cross(rprime, rpp) + text = TextMobject(r'$\frac{dB}{ds}$', r'$= -\tau$', r'$N$').shift(2*UP + 4*LEFT) + text.set_color_by_tex_to_color_map({ + r'$\frac{dB}{ds}$': YELLOW, + r'$N$': RED_C + }) + + dot = Dot().rotate(PI/2) + alpha = ValueTracker(0) + t = alpha.get_value + figure = ParametricFunction( + lambda t: np.array([ + np.sinh(t), + np.cosh(t), + 2*t + ]), t_min = -3, t_max = 3, color=BLUE + ).scale(0.5).move_to(ORIGIN) + vector_x = self.get_tangent_vector(t()%1, figure,scale=2) + vector_y = self.get_normal_vector(t(),figure,scale=2) + vector_x.add_updater( + lambda m: m.become( + self.get_tangent_vector(t()%1,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_y.get_start())) + + + + self.add_fixed_in_frame_mobjects(text) + self.play(FadeIn(figure), FadeIn(axes), FadeIn(text)) + self.begin_ambient_camera_rotation(rate = 0.1) + self.wait(1) + self.add(vector_x, vector_y,dot) + self.play(alpha.increment_value, 0.999, run_time=20, rate_func=rush_from) + self.wait(1) + self.remove(figure, vector_x, vector_y,dot) + self.play(FadeOut(figure), FadeOut(axes), FadeOut(text)) + + def get_tangent_vector(self, proportion, curve, dx=0.001, scale=1): + t = proportion.copy() + coord_i = curve.point_from_proportion(proportion) + rprime = np.array([np.cosh(t), np.sinh(t), 2]) + T = rprime / np.sqrt(np.dot(rprime, rprime)) + rpp = np.array([np.sinh(t), np.cosh(t), 0]) + n = rpp / np.dot(rpp, rpp) + # b = (np.cross(T, n)[0] - 0.5, np.cross(T, n)[1], coord_i[2] + 1) + b = np.cross(T, n) + # coord_f = curve.point_from_proportion(proportion + dx) + coord_f = b + reference_line = Line(coord_i,coord_f) + unit_vector = reference_line.get_unit_vector() * 1 + 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): + coord_i = curve.point_from_proportion(proportion) + coord_f = curve.point_from_proportion(proportion + dx) + t = proportion.copy()/7 + rpp = np.array([np.sinh(t), np.cosh(t), 0]) + length = np.sqrt(np.dot(rpp, rpp)) + length = 1/(1 + np.exp(-length)) + reference_line = Line(coord_i,coord_f).rotate(PI/2).set_width(length).scale(2) + unit_vector = reference_line.get_vector() * 0.7 + 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/file7_fs3.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file7_fs3.py new file mode 100644 index 0000000..698ca74 --- /dev/null +++ b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file7_fs3.py @@ -0,0 +1,194 @@ +from manimlib.imports import * + +class f(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): + axes = ThreeDAxes(**self.axes_config) + text = TextMobject(r'$r(t) = \left\langle\sinh{t}, \cosh{t}, 2t\right\rangle$').scale(0.7).shift(3*UP + 3*LEFT) + self.set_camera_orientation(phi = 75*DEGREES, theta=225*DEGREES) + + + + figure = ParametricFunction( + lambda t: np.array([ + np.sinh(t), + np.cosh(t), + 2*t + ]), t_min = -3, t_max = 3, color=ORANGE + ).scale(0.5).move_to(ORIGIN) + + dot = Dot(color=RED) + alpha = ValueTracker(0) + t = alpha.get_value + + vector_x = self.get_binormal_vector(t()%1, figure,scale=2) + vector_y = self.get_normal_vector(t(),figure,scale=2) + vector_z = self.get_tangent_vector(t(), figure, scale=2) + + vector_x.add_updater( + lambda m: m.become( + self.get_binormal_vector(t()%1,figure,scale=2) + ) + ) + vector_y.add_updater( + lambda m: m.become( + self.get_normal_vector(t(),figure,scale=2) + ) + ) + vector_z.add_updater( + lambda m: m.become( + self.get_tangent_vector(t(),figure,scale=2) + ) + ) + dot.add_updater( + lambda m: m.move_to(vector_x.get_start()) + ) + def curvature(t): + r = np.array([np.sinh(t), np.cosh(t), 2*t]) + rp = np.array([np.cosh(t), np.sinh(t), 2]) + rpp = np.array([np.sinh(t), np.cosh(t), 0]) + cp = np.cross(rp, rpp) + k = cp / (np.dot(rp, rp)**1.5) + return abs(k[0]) + + def torsion(t): + r = np.array([np.sinh(t), np.cosh(t), 2*t]) + rp = np.array([np.cosh(t), np.sinh(t), 2]) + rpp = np.array([np.sinh(t), np.cosh(t), 0]) + n = rpp / np.dot(rpp, rpp) + dbdt = np.array([2*np.sinh(t), 2*np.cosh(t), 0]) + tor = np.dot(dbdt, n) + return tor + + + + k = curvature(0.3) + k = "{:.2f}".format(k) + tor = torsion(0.3) + tor = "{:.2f}".format(tor) + kt1 = TextMobject(rf'At the given point, \\ $\kappa =$ {k} \\').scale(0.7).shift(3*UP + 4*RIGHT) + kt2 = TextMobject('$\implies \kappa$',r'$T$',r' is scaled as:').scale(0.7).next_to(kt1, DOWN, buff=0.1) + kt2.set_color_by_tex_to_color_map({ + '$T$': YELLOW + }) + tbt1 = TextMobject(rf'At the given point, \\ $\tau =$ {tor} \\').scale(0.7).shift(3*UP + 4*RIGHT) + tbt2 = TextMobject(r'$\implies \tau$',r'$B$',r' is scaled as:').scale(0.7).next_to(tbt1, DOWN, buff=0.1) + tbt2.set_color_by_tex_to_color_map({ + '$B$': GREEN_E + }) + ft = TextMobject(r'$\frac{dN}{ds}$',r'$ = -\kappa$',r'$T$', r'$ + \tau$',r'$B$ \\', r'and is given as:').scale(0.7).shift(3*UP + 4*RIGHT) + ft.set_color_by_tex_to_color_map({ + r'$\frac{dN}{ds}$': GREEN_SCREEN, + '$T$': YELLOW, + r'$B$ \\': GREEN_E + }) + + self.add_fixed_in_frame_mobjects(text) + self.play(FadeIn(figure), FadeIn(axes), FadeIn(text)) + # self.begin_ambient_camera_rotation(rate = 0.13) + self.wait(1) + self.add(vector_x, vector_y,vector_z,dot) + self.play(alpha.increment_value, 0.3, run_time=10, rate_func=rush_from) + self.wait(1) + # self.stop_ambient_camera_rotation() + # self.move_camera(phi = 75*DEGREES, theta=225*DEGREES) + square = Rectangle(width=3.2, fill_color=WHITE, fill_opacity=0.3, color=RED_C).rotate(40*DEGREES).shift(0.8*DOWN+1.2*RIGHT) + mat = [[0.7, 0.3], [1.0, -0.7]] + square = square.apply_matrix(mat).rotate(17*DEGREES).shift(2.1*DOWN+RIGHT) + tl, nl, bl = TextMobject(r'$T$', color=YELLOW).shift(2.8*RIGHT+0.5*DOWN), TextMobject(r'$N$', color=BLUE).shift(RIGHT), TextMobject(r'$B$', color=GREEN_E).shift(0.6*LEFT+0.5*DOWN) + self.add_fixed_in_frame_mobjects(tl, nl, bl) + self.play(FadeIn(VGroup(*[tl, nl, bl]))) + self.wait(3) + self.add_fixed_in_frame_mobjects(square) + self.play(FadeIn(square), FadeOut(VGroup(*[tl, nl, bl]))) + self.wait(2) + self.add_fixed_in_frame_mobjects(kt1) + self.play(FadeIn(kt1)) + self.wait(2) + self.add_fixed_in_frame_mobjects(kt2) + self.play(FadeIn(kt2)) + self.wait(2) + kt = self.get_tangent_vector(0.3, figure, scale = -4*float(k)) + tb = self.get_binormal_vector(0.3, figure, scale = 2*float(tor)) + self.play( + ReplacementTransform(vector_z, kt) + ) + self.wait(3) + self.add_fixed_in_frame_mobjects(tbt1) + self.play(FadeOut(VGroup(*[kt1, kt2])), FadeIn(tbt1)) + self.wait(2) + self.add_fixed_in_frame_mobjects(tbt2) + self.play(FadeIn(tbt2)) + self.wait(2) + self.play( + ReplacementTransform(vector_x, tb) + ) + self.wait(2) + self.add_fixed_in_frame_mobjects(ft) + self.play(FadeOut(VGroup(*[tbt1, tbt2])), FadeIn(ft)) + self.wait(2) + dnds = Arrow(dot.get_center() + np.array([-0.1,-0.25,0]), np.array([-4,-1,2]), color=GREEN_SCREEN) + dndsl = TextMobject(r'$\frac{dN}{ds}$', color=GREEN_SCREEN).shift(2.5*LEFT + 1.2*UP) + self.add_fixed_in_frame_mobjects(dndsl) + self.play(FadeIn(dnds), FadeIn(dndsl)) + self.wait(5) + self.play(FadeOut(VGroup(*[square, dot,vector_y, dnds, dndsl, text, ft, tb, kt]))) + self.play(FadeOut(figure), FadeOut(axes)) + + + def get_binormal_vector(self, proportion, curve, dx=0.001, scale=1): + t = proportion + coord_i = curve.point_from_proportion(proportion) + rprime = np.array([np.cosh(t), np.sinh(t), 2]) + T = rprime / np.sqrt(np.dot(rprime, rprime)) + rpp = np.array([np.sinh(t), np.cosh(t), 0]) + n = rpp / np.dot(rpp, rpp) + # b = (np.cross(T, n)[0] - 0.5, np.cross(T, n)[1], coord_i[2] + 1) + b = np.cross(T, n) + # coord_f = curve.point_from_proportion(proportion + dx) + coord_f = b + reference_line = Line(coord_i,coord_f) + unit_vector = reference_line.get_unit_vector() * scale + vector = Arrow(coord_i , coord_i + unit_vector, color = GREEN_E, buff=0) + return vector + + def get_normal_vector(self, proportion, curve, dx=0.001, scale=1): + coord_i = curve.point_from_proportion(proportion) + coord_f = curve.point_from_proportion(proportion + dx) + t = proportion.copy()/7 + rpp = np.array([np.sinh(t), np.cosh(t), 0]) + length = np.sqrt(np.dot(rpp, rpp)) + length = 1/(1 + np.exp(-length)) + reference_line = Line(coord_i,coord_f).rotate(PI/2).set_width(length).scale(2) + unit_vector = reference_line.get_unit_vector() * scale + vector = Arrow(coord_i, coord_i + unit_vector, color = BLUE, buff=0) + return vector + + def get_tangent_vector(self, proportion, curve, dx=0.001, scale=1): + coord_i = curve.point_from_proportion(proportion) + coord_f = curve.point_from_proportion(proportion + dx) + reference_line = Line(coord_i,coord_f).scale(2) + if scale < 0: + reference_line = Line(coord_i,coord_f).scale(2).rotate(360*DEGREES) + unit_vector = reference_line.get_unit_vector() * scale + vector = Arrow(coord_i, coord_i + unit_vector, color = YELLOW, buff=0) + return vector |