From 8096534204aeb06ea8e4b7a25c5bf4f7f1d52ffb Mon Sep 17 00:00:00 2001
From: Saarth Deshpande
Date: Wed, 1 Jul 2020 18:49:14 +0530
Subject: arc length video
---
.../arc-length-and-curvature/file1_arc_length.gif | Bin 0 -> 822369 bytes
.../arc-length-and-curvature/file1_arc_length.py | 325 +++++++++++++++++++++
.../file1_simple_visualization.gif | Bin 675451 -> 0 bytes
.../file1_simple_visualization.py | 69 -----
.../file2_circle_curvature.gif | Bin 346667 -> 0 bytes
.../file2_circle_curvature.py | 27 --
.../file2_simple_visualization.gif | Bin 0 -> 675451 bytes
.../file2_simple_visualization.py | 69 +++++
.../file3_circle_curvature.gif | Bin 0 -> 346667 bytes
.../file3_circle_curvature.py | 27 ++
.../file3_curvature_interpretation.gif | Bin 700862 -> 0 bytes
.../file3_curvature_interpretation.py | 42 ---
.../file4_curvature_interpretation.gif | Bin 0 -> 700862 bytes
.../file4_curvature_interpretation.py | 42 +++
.../file4_different_curvature_single_curve.gif | Bin 243868 -> 0 bytes
.../file4_different_curvature_single_curve.py | 78 -----
.../file5_different_curvature_single_curve.gif | Bin 0 -> 243868 bytes
.../file5_different_curvature_single_curve.py | 76 +++++
18 files changed, 539 insertions(+), 216 deletions(-)
create mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_arc_length.gif
create mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_arc_length.py
delete mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_simple_visualization.gif
delete mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_simple_visualization.py
delete mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file2_circle_curvature.gif
delete mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file2_circle_curvature.py
create mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file2_simple_visualization.gif
create mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file2_simple_visualization.py
create mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file3_circle_curvature.gif
create mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file3_circle_curvature.py
delete mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file3_curvature_interpretation.gif
delete mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file3_curvature_interpretation.py
create mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file4_curvature_interpretation.gif
create mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file4_curvature_interpretation.py
delete mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file4_different_curvature_single_curve.gif
delete mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file4_different_curvature_single_curve.py
create mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file5_different_curvature_single_curve.gif
create mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file5_different_curvature_single_curve.py
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_arc_length.gif b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_arc_length.gif
new file mode 100644
index 0000000..bbad112
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_arc_length.gif differ
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_arc_length.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_arc_length.py
new file mode 100644
index 0000000..75c19aa
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_arc_length.py
@@ -0,0 +1,325 @@
+# Contribution creidts: Somnath Pandit
+
+from manimlib.imports import *
+
+
+class LineIntegrationAsSum(GraphScene):
+ CONFIG = {
+ "x_min" : 0,
+ "x_max" : 10,
+ "y_min" : 0,
+ "y_max" : 6,
+ "graph_origin": ORIGIN+5*LEFT+3*DOWN,
+ "x_axis_width": 10,
+ "y_axis_height": 6 ,
+ "x_tick_frequency": 2,
+ "y_tick_frequency": 2,
+ "Func":lambda x : 1+x**1.3*np.exp(-.12*(x-2)**2)*np.sin(x/4),
+ "a": 1 ,"b": 9, "n": 15,
+ }
+
+ def construct(self):
+ X = RIGHT*self.x_axis_width/(self.x_max- self.x_min)
+ Y = UP*self.y_axis_height/(self.y_max- self.y_min)
+ self.X=X ;self.Y=Y
+
+ self.setup_axes(animate=False)
+
+
+ curve=self.get_graph(
+ self.Func,
+ x_min=self.a,
+ x_max=self.b,
+ )
+ curve.set_color([BLACK,BLUE,BLUE,BLUE,BLACK])
+ curve_label= self.get_graph_label(
+ curve,
+ label="\\text{Curve for integration:}",
+ x_val=4,
+ direction=UR,
+ buff=.6,
+ color=BLUE
+ )
+ self.curve=curve
+ self.curve_label=curve_label
+
+ self.get_vector_field()
+
+
+ self.play(ShowCreation(VGroup(curve,curve_label)))
+ self.wait(.6)
+ self.break_in_arcs()
+ self.show_the_sum()
+
+ self.wait(2)
+
+
+ def get_vector_field(self):
+ func = lambda v: np.array([
+ v[0], # x
+ -v[1], # y
+ 0 # z
+ ])
+ vector_field= VectorField(
+ func,
+ delta_x=1,
+ delta_y=1,
+ colors=[GREEN_A,GREEN_C],
+ length_func= lambda norm: .8*sigmoid(norm),
+ vector_config={
+ "stroke_width": 2
+ }
+ )
+
+ self.vector_field= vector_field
+
+
+ def break_in_arcs(self):
+
+ self.write_about_breaking()
+
+ dl=0.8
+ self.get_breakers(dl)
+ self.wait(2)
+ self.play(FadeOut(self.upto_break_text))
+ self.dl=dl
+
+ def write_about_breaking(self):
+ breaking_text=TextMobject("\\texttt{is broken}"," into small ", "subarcs")
+ breaking_text.set_color_by_tex_to_color_map({
+ "broken":RED,"subarcs": BLUE
+ })
+ breaking_text.next_to(self.curve_label,DOWN)
+ breaking_text.align_to(self.curve_label,LEFT)
+ self.play(
+ Write(breaking_text)
+ )
+
+ self.upto_break_text=VGroup(
+ self.curve_label,
+ breaking_text,
+ )
+
+ def get_breakers(self,dl):
+ point=self.a
+ points=[]
+ while point<(self.b-dl) :
+ start=point
+ end=point+dl
+ points += [end]
+ breaker=Line(
+ self.input_to_graph_point(start,self.curve),
+ self.input_to_graph_point(end,self.curve),
+ stroke_width=2,
+ color=RED,
+ )
+ breaker.rotate(PI/2).scale(.5)
+
+ point=end
+ self.play(FadeIn(breaker),run_time=.2)
+ # self.add(breaker)
+
+ del points[-1]
+ self.points=points
+
+
+ def show_the_sum(self):
+ at_any_points_text=TextMobject("At an arbitrary ","point", " in each ", "subarc")
+ at_any_points_text.set_color_by_tex_to_color_map({
+ "point":YELLOW , "subarc": BLUE
+ })
+ at_any_points_text.to_edge(TOP,buff=SMALL_BUFF)
+
+ evaluate_text=TextMobject("$\\vec F(x,y)$ ", "is evaluated").next_to(at_any_points_text,DOWN)
+ evaluate_text.set_color_by_tex("$\\vec F(x,y)$",ORANGE)
+
+ multiply_text=TextMobject("...is multiplied with ","$\\Delta s_i$")
+ multiply_text.set_color_by_tex("\\Delta s_i", BLUE)
+ multiply_text.next_to(at_any_points_text,DOWN)
+
+
+
+ self.at_any_points_text=at_any_points_text
+ self.evaluate_text=evaluate_text
+ self.multiply_text=multiply_text
+
+ dots=[]
+ for point in self.points:
+
+ dot=Dot(
+ point=self.input_to_graph_point(point,self.curve),
+ radius= .7*DEFAULT_DOT_RADIUS,
+ stroke_width= 0,
+ fill_opacity= 1.0,
+ color= YELLOW,
+ )
+ dots+=[dot]
+
+ self.play(
+ Write(at_any_points_text),
+ FadeIn(VGroup(*dots)),run_time=1.5
+ )
+ self.dots=dots
+
+ self.wait()
+ self.show_the_dot_product()
+ self.multiply_with_ds()
+ self.construct_equation()
+
+
+ def show_the_dot_product(self):
+ index=-(len(self.points)//3)
+ self.index=index
+
+ dot=self.dots[index]
+
+
+ dot_prod_text=TextMobject("Dot product of ", "$\\vec F(x_i,y_i)$", " and ","$\\vec T(x_i,y_i)$")
+ dot_prod_text.set_color_by_tex_to_color_map({
+ "\\vec F(x_i,y_i)":ORANGE ,
+ "\\vec T(x_i,y_i)": "#DC75CD" ,
+ })
+ dot_prod_text.to_edge(TOP,buff=SMALL_BUFF)
+
+
+ point_coord=TextMobject("$(x_i,y_i)$",color=YELLOW)
+ point_coord.next_to(dot,DL,buff=.01).scale(.8)
+
+ func_val=TextMobject("$\\vec F(x_i,y_i)$",color=ORANGE)
+ func_val.next_to(dot,UR).scale(.8)
+
+ self.dot_prod_text=dot_prod_text
+ self.func_val=func_val
+
+ dot.set_color(ORANGE).scale(1.2)
+
+
+ self.play(FadeIn(VGroup(point_coord,dot)))
+ self.play(Write(self.evaluate_text))
+ self.wait(1)
+ self.play(FadeOut(self.vector_field))
+ self.get_vector_and_tangent()
+ self.dot_product()
+
+
+ self.wait(2)
+ self.remove(point_coord)
+
+
+ def get_vector_and_tangent(self):
+ dot=self.dots[self.index]
+ self.show_specific_vectors(dot)
+ self.play(Write(self.func_val))
+ self.wait(1)
+ self.show_tangent(dot)
+ self.play(FadeIn(VGroup(*[
+ dot.set_color(ORANGE).scale(1.4)
+ for dot in self.dots ]
+ )))
+
+
+ def show_specific_vectors(self,dots):
+ for dot in dots:
+ vector=self.vector_field.get_vector(dot.get_center())
+ vector.set_color(ORANGE)
+
+ self.play(Write(vector),run_time=.2)
+
+
+ def show_tangent(self,dot):
+ tangent_sym=TextMobject("$\\vec T(x_i,y_i)$",color="#DC75CD").scale(.8)
+ x=dot.get_center()
+ angle=self.angle_of_tangent(
+ self.point_to_coords(x)[0],
+ self.curve,
+ dx=0.01
+ )
+ vect = Vector().rotate(angle,about_point=x)
+ vect.set_color("#DC75CD")
+ tangent=vect.next_to(x,DR,buff=0)
+ tangent_sym.next_to(tangent,DOWN,buff=.1)
+ self.play(Write(VGroup(tangent,tangent_sym)))
+
+ self.tangent_sym=tangent_sym
+
+ def dot_product(self):
+
+ dot_sym=Dot().next_to(self.func_val,RIGHT)
+
+ self.play(FadeOut(VGroup(
+ self.at_any_points_text,
+ self.evaluate_text
+ )))
+ self.play(Write(self.dot_prod_text))
+ self.play(
+ FadeIn(dot_sym),
+ ApplyMethod(
+ self.tangent_sym.next_to,
+ dot_sym, RIGHT
+ ))
+
+ self.dot_sym=dot_sym
+
+ def multiply_with_ds(self):
+ self.get_ds()
+
+ self.play(GrowFromCenter(self.ds_brace_group))
+ self.wait(2)
+ self.play(Write(self.multiply_text))
+ self.play(ApplyMethod(
+ self.ds_brace_label.next_to,
+ self.tangent_sym, RIGHT,buff=.15
+ ))
+
+
+
+ def get_ds(self):
+ p1= self.dots[self.index]
+ p2= self.dots[self.index+1]
+ ds_brace=Brace(VGroup(p1,p2),DL)
+ ds_brace.move_to(p1,UR)
+ ds_brace_label=ds_brace.get_text("$\Delta s_i$", buff = .05)
+ ds_brace_label.set_color(BLUE)
+ self.ds_brace=ds_brace
+ self.ds_brace_label=ds_brace_label
+ self.ds_brace_group=VGroup(ds_brace,ds_brace_label)
+
+
+ def construct_equation(self):
+ sum_up_text=TextMobject("and"," summed ", "for all `i's")
+ sum_up_text.set_color_by_tex("summed",PURPLE_A)
+ sum_up_text.next_to(self.multiply_text,DOWN,buff=MED_SMALL_BUFF)
+ sum_up_text.shift(LEFT)
+
+ sum_eqn=TextMobject("$$\\sum_i^{ } $$").set_color(PURPLE_A)
+ sum_eqn.move_to(self.graph_origin+6.5*self.X+4*self.Y)
+
+ line_integral_text=TextMobject("The"," line ","integral's value is: ").to_edge(TOP,buff=MED_SMALL_BUFF)
+ line_integral_text.set_color_by_tex("line",BLUE_C)
+ approx=TextMobject("$\\approx$",color=RED).next_to(sum_eqn,LEFT)
+ multipled=VGroup(
+ self.func_val,
+ self.dot_sym,
+ self.tangent_sym,
+ self.ds_brace_label
+ )
+
+
+ self.play(Write(sum_up_text))
+ self.show_specific_vectors(self.dots)
+ self.play(FadeIn(sum_eqn))
+ self.play(ApplyMethod(
+ multipled.next_to,sum_eqn,RIGHT
+ ))
+ self.wait()
+ self.play(FadeOut(VGroup(
+ self.dot_prod_text,
+ self.multiply_text,
+ sum_up_text
+ )))
+ self.play(Write(line_integral_text))
+ self.play(FadeIn(approx))
+
+
+
+#uploaded by Somnath Pandit.FSF2020_Line Integrals
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_simple_visualization.gif b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_simple_visualization.gif
deleted file mode 100644
index 3f7ecd1..0000000
Binary files a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_simple_visualization.gif and /dev/null differ
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_simple_visualization.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_simple_visualization.py
deleted file mode 100644
index 45058d7..0000000
--- a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_simple_visualization.py
+++ /dev/null
@@ -1,69 +0,0 @@
-from manimlib.imports import *
-
-class randomcurve(GraphScene):
- CONFIG = {
- "x_min": -4,
- "x_max": 6,
- "y_min": -6,
- "y_max": 10,
- "graph_origin": ORIGIN
- }
- def construct(self):
- intro = TextMobject('Consider the following curve.')
- mid = TextMobject(r'Notice how the direction of the unit tangent vectors\\changes with respect to the arc length.')
- outro = TextMobject(r'The rate of change of unit tangents with \\ respect to the arc length $ds$ is called curvature.\\Mathematically, curvature $ = k = \left|{\frac{dT}{ds}}\right|$')
-
- XTD = self.x_axis_width/(self.x_max- self.x_min)
- YTD = self.y_axis_height/(self.y_max- self.y_min)
-
- tgt1 = Arrow((-2.2*XTD,-0.5*YTD,0),(-1*XTD,1,0))
- tgt2 = Arrow((-1.2*XTD, 1.93*YTD,0),(0*XTD,1.6,0)).scale(1.2)
- tgt3 = Arrow((-0.3*XTD,3*YTD, 0), (1.5*XTD, 3*YTD,0))
- tgt4 = Arrow((1.4*XTD, 2*YTD,0),(2.4*XTD, 1*YTD,0)).scale(2.8)
- tgt5 = Arrow((2.4*XTD, 0, 0), (3.8*XTD,-2*YTD, 0)).scale(1.2).shift(0.26*RIGHT)
- tgt6 = Arrow((3.8*XTD,-1*YTD, 0), (4.8*XTD, -1*YTD, 0)).scale(2.8).shift(0.26*RIGHT)
- tgt7 = Arrow((5.3*XTD, 0, 0),(6.3*XTD,1,0)).shift(0.35*LEFT+0.1*DOWN).scale(1.3)
-
- dot1 = Dot(tgt1.get_start(), color = RED)
- dot2 = Dot(tgt2.get_start(), color = RED)
- dot3 = Dot(tgt3.get_start(), color = RED)
- dot4 = Dot(tgt4.get_start(), color = RED)
- dot5 = Dot(tgt5.get_start(), color = RED)
- dot6 = Dot(tgt6.get_start(), color = RED)
- dot7 = Dot(tgt7.get_start(), color = RED)
-
- arc = ArcBetweenPoints(dot1.get_center(), dot2.get_center(), color = GREEN_SCREEN, angle = 10*DEGREES).rotate(180*DEGREES)
-
- dots = VGroup(*[dot1, dot2, dot3, dot4, dot5, dot6, dot7])
-
- ds = CurvedArrow((-4, 2, 0), (tgt1.get_start() + tgt2.get_start()) / 2, color = YELLOW)
- ds_text = TextMobject(r'$ds$').next_to(ds, UP, buff = 0.1).shift(1.3*LEFT)
-
- self.setup_axes(hideaxes=True)
- graphobj = self.get_graph(self.curve)
- self.play(FadeIn(intro))
- self.wait(2)
- self.play(FadeOut(intro))
- self.setup_axes(hideaxes=False)
- self.play(ShowCreation(graphobj), FadeIn(dots), FadeIn(ds), FadeIn(ds_text), FadeIn(arc))
- self.wait(1)
- self.play(FadeOut(self.axes), FadeOut(arc), FadeOut(graphobj),FadeIn(mid), FadeOut(dots), FadeOut(ds), FadeOut(ds_text))
- self.wait(3)
- self.play(FadeOut(mid))
- self.play(FadeIn(self.axes), FadeIn(graphobj), FadeIn(dots))
-
- tangents = [tgt1, tgt2, tgt3, tgt4, tgt5, tgt6, tgt7]
- for tangent in tangents:
- self.play(ShowCreation(tangent), run_time = 0.2)
- self.wait(1)
- tangents = VGroup(*tangents)
- self.play(FadeOut(self.axes), FadeOut(graphobj), FadeOut(tangents), FadeOut(dots))
- self.wait(1)
- self.play(FadeIn(outro))
- self.wait(3)
- self.play(FadeOut(outro))
- self.wait(1)
-
-
- def curve(self, x):
- return 3 - (3653*x**2)/5292 + (2477*x**3)/31752 + (13*x**4)/784 - (17*x**5)/5292 + (17*x**6)/63504
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file2_circle_curvature.gif b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file2_circle_curvature.gif
deleted file mode 100644
index 989a3b7..0000000
Binary files a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file2_circle_curvature.gif and /dev/null differ
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file2_circle_curvature.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file2_circle_curvature.py
deleted file mode 100644
index 232ac41..0000000
--- a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file2_circle_curvature.py
+++ /dev/null
@@ -1,27 +0,0 @@
-from manimlib.imports import *
-
-class circleC(GraphScene):
- CONFIG = {
- "x_min": -6,
- "x_max": 6,
- "y_min": -6,
- "y_max": 6,
- "graph_origin": ORIGIN,
- "x_axis_width": 12,
- "y_axis_height": 12
- }
- def construct(self):
- epiphany = TextMobject(r'Driving a vehicle on which of \\ the two paths would be easier?').scale(0.6).shift(3.5*LEFT + 3*UP)
- outro = TextMobject(r'The larger path, due to its \\ smaller curvature, since $k = \frac{1}{R}$.').scale(0.6).shift(3.7*LEFT + 3*UP)
- XTD = self.x_axis_width/(self.x_max- self.x_min)
- YTD = self.y_axis_height/(self.y_max- self.y_min)
-
- circle = Circle(radius = 2, color = BLUE)
- circle2 = Circle(radius = 3, color = GREEN_E)
-
- self.setup_axes(hideaxes=True)
- self.play(FadeIn(self.axes), Write(circle, run_time = 2), FadeIn(epiphany))
- self.play(Write(circle2, run_time = 3))
- self.play(ReplacementTransform(epiphany, outro))
- self.wait(2)
- self.play(FadeOut(VGroup(*[self.axes, circle, circle2, epiphany, outro])))
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file2_simple_visualization.gif b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file2_simple_visualization.gif
new file mode 100644
index 0000000..3f7ecd1
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file2_simple_visualization.gif differ
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file2_simple_visualization.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file2_simple_visualization.py
new file mode 100644
index 0000000..45058d7
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file2_simple_visualization.py
@@ -0,0 +1,69 @@
+from manimlib.imports import *
+
+class randomcurve(GraphScene):
+ CONFIG = {
+ "x_min": -4,
+ "x_max": 6,
+ "y_min": -6,
+ "y_max": 10,
+ "graph_origin": ORIGIN
+ }
+ def construct(self):
+ intro = TextMobject('Consider the following curve.')
+ mid = TextMobject(r'Notice how the direction of the unit tangent vectors\\changes with respect to the arc length.')
+ outro = TextMobject(r'The rate of change of unit tangents with \\ respect to the arc length $ds$ is called curvature.\\Mathematically, curvature $ = k = \left|{\frac{dT}{ds}}\right|$')
+
+ XTD = self.x_axis_width/(self.x_max- self.x_min)
+ YTD = self.y_axis_height/(self.y_max- self.y_min)
+
+ tgt1 = Arrow((-2.2*XTD,-0.5*YTD,0),(-1*XTD,1,0))
+ tgt2 = Arrow((-1.2*XTD, 1.93*YTD,0),(0*XTD,1.6,0)).scale(1.2)
+ tgt3 = Arrow((-0.3*XTD,3*YTD, 0), (1.5*XTD, 3*YTD,0))
+ tgt4 = Arrow((1.4*XTD, 2*YTD,0),(2.4*XTD, 1*YTD,0)).scale(2.8)
+ tgt5 = Arrow((2.4*XTD, 0, 0), (3.8*XTD,-2*YTD, 0)).scale(1.2).shift(0.26*RIGHT)
+ tgt6 = Arrow((3.8*XTD,-1*YTD, 0), (4.8*XTD, -1*YTD, 0)).scale(2.8).shift(0.26*RIGHT)
+ tgt7 = Arrow((5.3*XTD, 0, 0),(6.3*XTD,1,0)).shift(0.35*LEFT+0.1*DOWN).scale(1.3)
+
+ dot1 = Dot(tgt1.get_start(), color = RED)
+ dot2 = Dot(tgt2.get_start(), color = RED)
+ dot3 = Dot(tgt3.get_start(), color = RED)
+ dot4 = Dot(tgt4.get_start(), color = RED)
+ dot5 = Dot(tgt5.get_start(), color = RED)
+ dot6 = Dot(tgt6.get_start(), color = RED)
+ dot7 = Dot(tgt7.get_start(), color = RED)
+
+ arc = ArcBetweenPoints(dot1.get_center(), dot2.get_center(), color = GREEN_SCREEN, angle = 10*DEGREES).rotate(180*DEGREES)
+
+ dots = VGroup(*[dot1, dot2, dot3, dot4, dot5, dot6, dot7])
+
+ ds = CurvedArrow((-4, 2, 0), (tgt1.get_start() + tgt2.get_start()) / 2, color = YELLOW)
+ ds_text = TextMobject(r'$ds$').next_to(ds, UP, buff = 0.1).shift(1.3*LEFT)
+
+ self.setup_axes(hideaxes=True)
+ graphobj = self.get_graph(self.curve)
+ self.play(FadeIn(intro))
+ self.wait(2)
+ self.play(FadeOut(intro))
+ self.setup_axes(hideaxes=False)
+ self.play(ShowCreation(graphobj), FadeIn(dots), FadeIn(ds), FadeIn(ds_text), FadeIn(arc))
+ self.wait(1)
+ self.play(FadeOut(self.axes), FadeOut(arc), FadeOut(graphobj),FadeIn(mid), FadeOut(dots), FadeOut(ds), FadeOut(ds_text))
+ self.wait(3)
+ self.play(FadeOut(mid))
+ self.play(FadeIn(self.axes), FadeIn(graphobj), FadeIn(dots))
+
+ tangents = [tgt1, tgt2, tgt3, tgt4, tgt5, tgt6, tgt7]
+ for tangent in tangents:
+ self.play(ShowCreation(tangent), run_time = 0.2)
+ self.wait(1)
+ tangents = VGroup(*tangents)
+ self.play(FadeOut(self.axes), FadeOut(graphobj), FadeOut(tangents), FadeOut(dots))
+ self.wait(1)
+ self.play(FadeIn(outro))
+ self.wait(3)
+ self.play(FadeOut(outro))
+ self.wait(1)
+
+
+ def curve(self, x):
+ return 3 - (3653*x**2)/5292 + (2477*x**3)/31752 + (13*x**4)/784 - (17*x**5)/5292 + (17*x**6)/63504
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file3_circle_curvature.gif b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file3_circle_curvature.gif
new file mode 100644
index 0000000..989a3b7
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file3_circle_curvature.gif differ
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file3_circle_curvature.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file3_circle_curvature.py
new file mode 100644
index 0000000..232ac41
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file3_circle_curvature.py
@@ -0,0 +1,27 @@
+from manimlib.imports import *
+
+class circleC(GraphScene):
+ CONFIG = {
+ "x_min": -6,
+ "x_max": 6,
+ "y_min": -6,
+ "y_max": 6,
+ "graph_origin": ORIGIN,
+ "x_axis_width": 12,
+ "y_axis_height": 12
+ }
+ def construct(self):
+ epiphany = TextMobject(r'Driving a vehicle on which of \\ the two paths would be easier?').scale(0.6).shift(3.5*LEFT + 3*UP)
+ outro = TextMobject(r'The larger path, due to its \\ smaller curvature, since $k = \frac{1}{R}$.').scale(0.6).shift(3.7*LEFT + 3*UP)
+ XTD = self.x_axis_width/(self.x_max- self.x_min)
+ YTD = self.y_axis_height/(self.y_max- self.y_min)
+
+ circle = Circle(radius = 2, color = BLUE)
+ circle2 = Circle(radius = 3, color = GREEN_E)
+
+ self.setup_axes(hideaxes=True)
+ self.play(FadeIn(self.axes), Write(circle, run_time = 2), FadeIn(epiphany))
+ self.play(Write(circle2, run_time = 3))
+ self.play(ReplacementTransform(epiphany, outro))
+ self.wait(2)
+ self.play(FadeOut(VGroup(*[self.axes, circle, circle2, epiphany, outro])))
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file3_curvature_interpretation.gif b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file3_curvature_interpretation.gif
deleted file mode 100644
index 22a450a..0000000
Binary files a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file3_curvature_interpretation.gif and /dev/null differ
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file3_curvature_interpretation.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file3_curvature_interpretation.py
deleted file mode 100644
index d8dd0a4..0000000
--- a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file3_curvature_interpretation.py
+++ /dev/null
@@ -1,42 +0,0 @@
-from manimlib.imports import *
-
-class interpretation(Scene):
- def construct(self):
- tgt = Vector((1, 2, 0), color = YELLOW)
- tgtText = TextMobject(r'$r\prime (t)$').next_to(tgt, UP, buff = 0).scale(0.7)
- tgt2 = DashedLine((0,0,0),(1, 2, 0), color = GRAY).shift(DOWN + 2*RIGHT)
-
- nm = Vector((2, -1, 0), color = BLUE)
- nmText = TextMobject(r'$r\prime\prime (t)$').next_to(nm, DOWN+RIGHT, buff = 0).scale(0.7)
- nm2 = DashedLine((0,0,0),(2, -1, 0), color = GRAY).shift(2*UP + RIGHT)
- square = Square(fill_color = WHITE, fill_opacity = 0.2).rotate(63*DEGREES).shift(0.5*UP +1.5*RIGHT).scale(1.1)
- square.set_stroke(width = 0.1)
- arrow = CurvedArrow(square.get_center() + np.array([2,1,0]), square.get_center() + np.array([0.5,0,0]))
- arrowText = TextMobject(r'$r\prime (t)\times r\prime\prime (t)$').next_to(arrow.get_start(), DOWN+1*RIGHT, buff = 0).scale(0.7)
-
- text1 = TextMobject(r'$\left|\frac{dT}{ds}\right| = \frac{\left|\frac{dT}{dt}\right|}{\left|\frac{ds}{dt}\right|}$').shift(UP+3*LEFT)
- text2 = TextMobject(r'$\left|\frac{dT}{ds}\right| = \frac{\frac{r\prime\prime (t)}{\left| r\prime (t)\right|}\times\frac{r\prime (t)}{\left| r\prime (t)\right|}}{\left|r\prime (t)\right|}$').next_to(text1, DOWN, buff = 0.1)
- unit = VGroup(*[tgt, tgt2, nm, nm2])
-
- # self.play(FadeIn(VGroup(*[tgt, tgt2, nm, nm2, nmText, tgtText, square, arrow, arrowText])))
- tgt2text = TextMobject(r'$\frac{r\prime (t)}{\left| r\prime (t)\right|}$').shift(1.1*UP).scale(0.7).rotate(63*DEGREES )
- nm2text = TextMobject(r'$\frac{r\prime\prime (t)}{\left| r\prime (t)\right|}$').scale(0.7).shift(0.7*RIGHT+0.8*DOWN).rotate(-25*DEGREES)
- unit2 = unit.copy().scale(0.5).shift(0.75*LEFT+0.25*DOWN)
-
- self.play(FadeIn(VGroup(*[tgt, tgtText])))
- self.wait(1)
- self.play(FadeIn(VGroup(*[nm, nmText])))
- self.wait(1)
- self.play(FadeIn(VGroup(*[tgt2, nm2])))
- self.wait(1)
- self.play(FadeIn(VGroup(*[square, arrow, arrowText])))
- self.wait(1)
- self.play(FadeIn(unit2))
- self.wait(1)
- self.play(FadeIn(VGroup(*[tgt2text, nm2text])))
- self.wait(1)
- self.play(FadeIn(text1))
- self.wait(1)
- self.play(FadeIn(text2))
- self.wait(2)
- self.play(FadeOut(VGroup(*[tgt2text, nm2text, text1, text2, tgt, tgtText,nm, nmText,tgt2, nm2,square, arrow, arrowText,unit2])))
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file4_curvature_interpretation.gif b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file4_curvature_interpretation.gif
new file mode 100644
index 0000000..22a450a
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file4_curvature_interpretation.gif differ
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file4_curvature_interpretation.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file4_curvature_interpretation.py
new file mode 100644
index 0000000..d8dd0a4
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file4_curvature_interpretation.py
@@ -0,0 +1,42 @@
+from manimlib.imports import *
+
+class interpretation(Scene):
+ def construct(self):
+ tgt = Vector((1, 2, 0), color = YELLOW)
+ tgtText = TextMobject(r'$r\prime (t)$').next_to(tgt, UP, buff = 0).scale(0.7)
+ tgt2 = DashedLine((0,0,0),(1, 2, 0), color = GRAY).shift(DOWN + 2*RIGHT)
+
+ nm = Vector((2, -1, 0), color = BLUE)
+ nmText = TextMobject(r'$r\prime\prime (t)$').next_to(nm, DOWN+RIGHT, buff = 0).scale(0.7)
+ nm2 = DashedLine((0,0,0),(2, -1, 0), color = GRAY).shift(2*UP + RIGHT)
+ square = Square(fill_color = WHITE, fill_opacity = 0.2).rotate(63*DEGREES).shift(0.5*UP +1.5*RIGHT).scale(1.1)
+ square.set_stroke(width = 0.1)
+ arrow = CurvedArrow(square.get_center() + np.array([2,1,0]), square.get_center() + np.array([0.5,0,0]))
+ arrowText = TextMobject(r'$r\prime (t)\times r\prime\prime (t)$').next_to(arrow.get_start(), DOWN+1*RIGHT, buff = 0).scale(0.7)
+
+ text1 = TextMobject(r'$\left|\frac{dT}{ds}\right| = \frac{\left|\frac{dT}{dt}\right|}{\left|\frac{ds}{dt}\right|}$').shift(UP+3*LEFT)
+ text2 = TextMobject(r'$\left|\frac{dT}{ds}\right| = \frac{\frac{r\prime\prime (t)}{\left| r\prime (t)\right|}\times\frac{r\prime (t)}{\left| r\prime (t)\right|}}{\left|r\prime (t)\right|}$').next_to(text1, DOWN, buff = 0.1)
+ unit = VGroup(*[tgt, tgt2, nm, nm2])
+
+ # self.play(FadeIn(VGroup(*[tgt, tgt2, nm, nm2, nmText, tgtText, square, arrow, arrowText])))
+ tgt2text = TextMobject(r'$\frac{r\prime (t)}{\left| r\prime (t)\right|}$').shift(1.1*UP).scale(0.7).rotate(63*DEGREES )
+ nm2text = TextMobject(r'$\frac{r\prime\prime (t)}{\left| r\prime (t)\right|}$').scale(0.7).shift(0.7*RIGHT+0.8*DOWN).rotate(-25*DEGREES)
+ unit2 = unit.copy().scale(0.5).shift(0.75*LEFT+0.25*DOWN)
+
+ self.play(FadeIn(VGroup(*[tgt, tgtText])))
+ self.wait(1)
+ self.play(FadeIn(VGroup(*[nm, nmText])))
+ self.wait(1)
+ self.play(FadeIn(VGroup(*[tgt2, nm2])))
+ self.wait(1)
+ self.play(FadeIn(VGroup(*[square, arrow, arrowText])))
+ self.wait(1)
+ self.play(FadeIn(unit2))
+ self.wait(1)
+ self.play(FadeIn(VGroup(*[tgt2text, nm2text])))
+ self.wait(1)
+ self.play(FadeIn(text1))
+ self.wait(1)
+ self.play(FadeIn(text2))
+ self.wait(2)
+ self.play(FadeOut(VGroup(*[tgt2text, nm2text, text1, text2, tgt, tgtText,nm, nmText,tgt2, nm2,square, arrow, arrowText,unit2])))
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file4_different_curvature_single_curve.gif b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file4_different_curvature_single_curve.gif
deleted file mode 100644
index 3b78b5f..0000000
Binary files a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file4_different_curvature_single_curve.gif and /dev/null differ
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file4_different_curvature_single_curve.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file4_different_curvature_single_curve.py
deleted file mode 100644
index 56b7fbb..0000000
--- a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file4_different_curvature_single_curve.py
+++ /dev/null
@@ -1,78 +0,0 @@
-from manimlib.imports import *
-
-class GR(GraphScene):
- CONFIG = {
- "x_axis_label": "",
- "y_axis_label": "",
- "x_min": -4,
- "x_max": 6,
- "y_min": -6,
- "y_max": 10,
- "graph_origin": ORIGIN,
- 'x_tick_frequency': 20,
- 'y_tick_frequency': 20
- }
-
- def construct(self):
-
- self.setup_axes()
- def curve(x):
- return 3 - (3653*x**2)/5292 + (2477*x**3)/31752 + (13*x**4)/784 - (17*x**5)/5292 + (17*x**6)/63504
-
- graph = FunctionGraph(curve, x_min=-3, x_max=6, stroke_width = 2, color = BLUE)
-
- tracker = ValueTracker(-3)
-
- text = TextMobject(r'$\because R_{1} > R_{2}$, the curvature at \\ point $P_{1}$ is less than that \\ at point $P_{2}$ as $\kappa = \frac{1}{R}$').shift(3.2*RIGHT+3*UP).scale(0.6)
-
- dot1 = Dot((0,3,0), color = YELLOW)
- dot1label = TextMobject(r'$P_{1}$').next_to(dot1, UP+RIGHT, buff = 0.1)
- dot2 = Dot((4,-1, 0), color = YELLOW)
- dot2label = TextMobject(r'$P_{2}$').next_to(dot2, DOWN, buff = 0.1)
- dots = VGroup(*[dot1, dot2, dot1label, dot2label])
-
- def get_tangent_line():
- line = Line(
- ORIGIN, 2 * RIGHT,
- color=RED,
- stroke_width=4,
- )
- dx = 0.0001
-
- x = tracker.get_value()
- p0 = np.array([x-dx,curve(x-dx),0])
- p1 = np.array([x, curve(x), 0])
- p2 = np.array([x + dx, curve(x + dx), 0])
-
- angle = angle_of_vector(p2 - p1)
- line.rotate(angle)
- line.move_to(p0)
- return line
-
- circle1 = Circle(radius = 0.8, color = GREY, opacity = 0.2).shift(2.2*UP)
- tgt1 = Line((-2,3,0), (2,3,0), color = GREY, opacity = 0.2).scale(0.4)
-
- r1 = Line(circle1.get_center(), circle1.get_center() + np.array([0,0.8,0]), color=GREEN_SCREEN)
- r1label = TextMobject(r'$R_{1}$',color=WHITE).next_to(r1, RIGHT, buff = 0.1).scale(0.6)
-
- curvature1 = VGroup(*[circle1, tgt1, r1, r1label])
-
- circle2 = Circle(radius = 0.6, color = GREY, opacity = 0.2).shift(0.4*DOWN + 4*RIGHT)
- tgt2 = Line((4,-2,0), (6, -2, 0), color = GREY, opacity = 0.2).scale(0.5).shift(LEFT + UP)
-
- r2 = Line(circle2.get_center(), circle2.get_center() + np.array([0,-0.6,0]), color=GREEN_SCREEN)
- r2label = TextMobject(r'$R_{2}$', color=WHITE).next_to(r2, 0.9*RIGHT, buff = 0).scale(0.6)
-
- curvature2 = VGroup(*[circle2, tgt2, r2, r2label])
-
- line = always_redraw(get_tangent_line)
-
- self.add(graph,line, dots, text)
- self.wait(1.2)
- self.play(tracker.set_value, 0, rate_func=smooth, run_time=5)
- self.play(FadeIn(curvature1))
- self.play(tracker.set_value, 4, rate_func=smooth, run_time=5)
- self.play(FadeIn(curvature2))
- self.play(tracker.set_value, 6, rate_func=smooth, run_time=3)
- self.play(FadeOut(VGroup(*[curvature1, curvature2, graph, self.axes, line, dots, text])))
- self.wait()
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file5_different_curvature_single_curve.gif b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file5_different_curvature_single_curve.gif
new file mode 100644
index 0000000..3b78b5f
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file5_different_curvature_single_curve.gif differ
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file5_different_curvature_single_curve.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file5_different_curvature_single_curve.py
new file mode 100644
index 0000000..0dc06bb
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file5_different_curvature_single_curve.py
@@ -0,0 +1,76 @@
+from manimlib.imports import *
+
+class GR(GraphScene):
+ CONFIG = {
+ "x_axis_label": "",
+ "y_axis_label": "",
+ "x_min": -4,
+ "x_max": 6,
+ "y_min": -6,
+ "y_max": 10,
+ "graph_origin": ORIGIN,
+ 'x_tick_frequency': 20,
+ 'y_tick_frequency': 20
+ }
+
+ def construct(self):
+
+ self.setup_axes()
+ def curve(x):
+ return 3 - (3653*x**2)/5292 + (277*x**3)/31752 + (13*x**4)/784 - (17*x**5)/5292 + (170*x**6)/63504
+
+ graph = FunctionGraph(curve, x_min=-2, x_max=6, stroke_width = 2, color = BLUE)
+
+ tracker = ValueTracker(-2)
+
+ text = TextMobject(r'$\because R_{1} > R_{2}$, the curvature at \\ point $P_{1}$ is less than that \\ at point $P_{2}$ as $\kappa = \frac{1}{R}$').shift(3.2*LEFT+3*UP).scale(0.6)
+
+ dot1 = Dot((0,3,0), color = YELLOW)
+ dot1label = TextMobject(r'$P_{1}$').next_to(dot1, UP+RIGHT, buff = 0.1)
+ dot2 = Dot((2.9,-0.47, 0), color = YELLOW)
+ dot2label = TextMobject(r'$P_{2}$').next_to(dot2, DOWN, buff = 0.1)
+ dots = VGroup(*[dot1, dot2, dot1label, dot2label])
+
+ def get_tangent_line():
+ line = Line(
+ ORIGIN, 2 * RIGHT,
+ color=RED,
+ stroke_width=4,
+ )
+ dx = 0.0001
+
+ x = tracker.get_value()
+ p0 = np.array([x-dx,curve(x-dx),0])
+ p1 = np.array([x, curve(x), 0])
+ p2 = np.array([x + dx, curve(x + dx), 0])
+
+ angle = angle_of_vector(p2 - p1)
+ line.rotate(angle)
+ line.move_to(p0)
+ return line
+
+ circle1 = Circle(radius = 0.8, color = GREY, opacity = 0.2).shift(2.2*UP)
+ tgt1 = Line((-2,3,0), (2,3,0), color = GREY, opacity = 0.2).scale(0.4)
+
+ r1 = Line(circle1.get_center(), circle1.get_center() + np.array([0,0.8,0]), color=GREEN_SCREEN)
+ r1label = TextMobject(r'$R_{1}$',color=WHITE).next_to(r1, RIGHT, buff = 0.1).scale(0.6)
+
+ curvature1 = VGroup(*[circle1, tgt1, r1, r1label])
+
+ circle2 = Circle(radius = 0.2, color = GREY, opacity = 0.2).shift(0.3*DOWN + 2.9*RIGHT)
+ tgt2 = Line((4,-2,0), (6, -2, 0), color = GREY, opacity = 0.2).scale(0.5).shift(2.1*LEFT + 1.5*UP)
+
+ r2 = Line(circle2.get_center(), circle2.get_center() - np.array([0,0.2,0]), color=GREEN_SCREEN)
+ r2label = TextMobject(r'$R_{2}$', color=WHITE).next_to(r2.get_start(), np.array([0,0,0]), buff = 0).scale(0.4)
+
+ curvature2 = VGroup(*[circle2, tgt2, r2, r2label])
+
+ line = always_redraw(get_tangent_line)
+
+ self.add(graph, line, dots, text)
+ self.wait(1.2)
+ self.play(tracker.set_value, 4, rate_func=smooth, run_time=10)
+ self.play(FadeIn(curvature1), FadeIn(curvature2))
+ self.wait(2)
+ self.play(FadeOut(VGroup(*[curvature1, curvature2, graph, self.axes, line, dots, text])))
+ self.wait()
--
cgit
From ba2e5d704cdafd73cc0e0dab91fcff110ffaf400 Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Fri, 3 Jul 2020 19:53:49 +0530
Subject: Delete file1_multivar_func_examples.py
---
.../file1_multivar_func_examples.py | 167 ---------------------
1 file changed, 167 deletions(-)
delete mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/file1_multivar_func_examples.py
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/file1_multivar_func_examples.py b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/file1_multivar_func_examples.py
deleted file mode 100644
index 55b2b7e..0000000
--- a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/file1_multivar_func_examples.py
+++ /dev/null
@@ -1,167 +0,0 @@
-from manimlib.imports import *
-
-class Examples1(GraphScene):
- def construct(self):
-
- rectangle = Rectangle(height = 3, width = 4, color = GREEN)
- rectangle_area_func = TexMobject("Area", "=", "f(", "Length", ",", "Breadth", ")").scale(0.6)
- rectangle_area_func[0].set_color(RED_C)
- rectangle_area_func[2].set_color(ORANGE)
- rectangle_area_func[3].set_color(YELLOW_C)
- rectangle_area_func[5].set_color(BLUE_C)
- rectangle_area_func[6].set_color(ORANGE)
-
-
- rectangle_area = TexMobject("Area", "=", "Length", "\\times", "Breadth").scale(0.6)
- rectangle_area[0].set_color(RED_C)
- rectangle_area[2].set_color(YELLOW_C)
- rectangle_area[4].set_color(BLUE_C)
-
-
- square = Square(side_length = 5, color = PURPLE)
- square_area_func = TexMobject("Area", "=", "f(", "Length", ")")
- square_area_func[0].set_color(GREEN_C)
- square_area_func[2].set_color(ORANGE)
- square_area_func[3].set_color(BLUE_C)
- square_area_func[4].set_color(ORANGE)
-
- square_area = TexMobject("Area", "=", "Length^2")
- square_area[0].set_color(GREEN_C)
- square_area[2].set_color(BLUE_C)
-
-
- circle = Circle(radius = 2, color = PINK)
- circle_area_func = TexMobject("Area", "=", "f(", "r", ")")
- circle_area_func[0].set_color(YELLOW_C)
- circle_area_func[2].set_color(ORANGE)
- circle_area_func[3].set_color(GREEN_C)
- circle_area_func[4].set_color(ORANGE)
-
- circle_area = TexMobject("Area", "=", "\\pi", "r^2")
- circle_area[0].set_color(YELLOW_C)
- circle_area[2].set_color(BLUE_C)
- circle_area[3].set_color(GREEN_C)
-
- radius = Line(ORIGIN,2*RIGHT, color = RED_C)
-
-
-
- braces_rect1 = Brace(rectangle, LEFT)
- eq_text1 = braces_rect1.get_text("Length").set_color(YELLOW_C)
- braces_rect2 = Brace(rectangle, UP)
- eq_text2 = braces_rect2.get_text("Breadth").set_color(BLUE_C)
-
- braces_square = Brace(square, LEFT)
- braces_square_text = braces_square.get_text("Length").set_color(BLUE_C)
-
- radius_text = TexMobject("r", color = GREEN_C).next_to(radius,UP)
-
-
-
- self.play(ShowCreation(rectangle))
- self.wait(1)
- self.play(GrowFromCenter(braces_rect1),Write(eq_text1),GrowFromCenter(braces_rect2),Write(eq_text2))
- self.wait(1)
- self.play(Write(rectangle_area_func))
- self.wait(1)
- self.play(Transform(rectangle_area_func, rectangle_area))
- self.wait(1)
- self.play(FadeOut(braces_rect1),FadeOut(eq_text1),FadeOut(braces_rect2),FadeOut(eq_text2),FadeOut(rectangle_area_func))
-
-
- self.play(Transform(rectangle, square))
- self.wait(1)
- self.play(GrowFromCenter(braces_square),Write(braces_square_text))
- self.wait(1)
- self.play(Write(square_area_func))
- self.wait(1)
- self.play(Transform(square_area_func, square_area))
- self.wait(1)
- self.play(FadeOut(braces_square),FadeOut(braces_square_text),FadeOut(square_area_func))
-
-
- self.play(Transform(rectangle, circle))
- self.wait(1)
- self.play(ShowCreation(radius),Write(radius_text))
- self.wait(1)
- self.play(FadeOut(radius_text),FadeOut(radius))
- self.wait(1)
- self.play(Write(circle_area_func))
- self.wait(1)
- self.play(Transform(circle_area_func, circle_area))
- self.wait(1)
- self.play(FadeOut(circle_area_func))
-
-
-
-class Examples2(ThreeDScene):
- def construct(self):
- axes = ThreeDAxes()
-
- rectangle_x_y_0 = Polygon(np.array([-1,-2,0]),np.array([-1,2,0]),np.array([1,2,0]),np.array([1,-2,0]),np.array([-1,-2,0]), color = RED_E, fill_color = RED_C, fill_opacity = 0.1)
- rectangle_x_y_3 = Polygon(np.array([-1,-2,3]),np.array([-1,2,3]),np.array([1,2,3]),np.array([1,-2,3]),np.array([-1,-2,3]), color = RED_E, fill_color = RED_C, fill_opacity = 0.1)
-
- rectangle_y_z_1 = Polygon(np.array([1,-2,3]),np.array([1,2,3]),np.array([1,2,0]),np.array([1,-2,0]),np.array([1,-2,3]), color = RED_E, fill_color = RED_C, fill_opacity = 0.1)
- rectangle_y_z_minus_1 = Polygon(np.array([-1,-2,3]),np.array([-1,2,3]),np.array([-1,2,0]),np.array([-1,-2,0]),np.array([-1,-2,3]), color = RED_E, fill_color = RED_C, fill_opacity = 0.1)
-
- rectangle_x_z_2 = Polygon(np.array([1,2,3]),np.array([-1,2,3]),np.array([-1,2,0]),np.array([1,2,0]),np.array([1,2,3]), color = RED_E, fill_color = RED_C, fill_opacity = 0.1)
- rectangle_x_z_minus_2 = Polygon(np.array([1,-2,3]),np.array([-1,-2,3]),np.array([-1,-2,0]),np.array([1,-2,0]),np.array([1,-2,3]), color = RED_E, fill_color = RED_C, fill_opacity = 0.1)
-
- box = VGroup(rectangle_x_y_0, rectangle_x_y_3, rectangle_y_z_1, rectangle_y_z_minus_1, rectangle_x_z_2, rectangle_x_z_minus_2)
-
- braces_rectangle_x_y_0 = Line(np.array([1,2,0]), np.array([1,-2,0]), color = BLUE_C)
- braces_rectangle_x_y_0_text = TextMobject("Length").set_color(BLUE_C).move_to(np.array([2,-1,0]))
-
- braces_rectangle_y_z_1 = Line(np.array([1,2,0]), np.array([1,2,3]), color = YELLOW_C)
- braces_rectangle_y_z_1_text = TextMobject("Height").set_color(YELLOW_C).move_to(np.array([2,3.8,2]))
-
- braces_rectangle_x_z_2 = Line(np.array([1,2,3]), np.array([-1,2,3]), color = PURPLE)
- braces_rectangle_x_z_2_text = TextMobject("Breadth").set_color(PURPLE).move_to(np.array([0,3.8,3.3]))
-
- box_area_func = TexMobject("Area =", "f(", "Length", ",", "Breadth", ",", "Height", ")").move_to(4*LEFT+3.5*UP).scale(0.6)
- box_area_func[0].set_color(GREEN_C)
- box_area_func[1].set_color(ORANGE)
- box_area_func[2].set_color(BLUE_C)
- box_area_func[4].set_color(PURPLE)
- box_area_func[6].set_color(YELLOW_C)
- box_area_func[7].set_color(ORANGE)
-
- box_area_func_2 = TexMobject("Area =", "Length", "\\times", "Breadth", "\\times", "Height").move_to(4*LEFT+3.5*UP).scale(0.6)
- box_area_func_2[0].set_color(GREEN_C)
- box_area_func_2[1].set_color(BLUE_C)
- box_area_func_2[3].set_color(PURPLE)
- box_area_func_2[5].set_color(YELLOW_C)
-
-
- self.set_camera_orientation(phi=70 * DEGREES, theta = 45*DEGREES)
-
- self.add(axes)
-
- axis = TextMobject(r"X",r"Y",r"Z")
- axis[0].move_to(6*RIGHT)
- axis[1].move_to(6*UP)
- axis[2].move_to(3.7*UP)
-
- self.add_fixed_in_frame_mobjects(axis[2])
- self.add_fixed_orientation_mobjects(axis[0])
- self.add_fixed_orientation_mobjects(axis[1])
-
- self.play(ShowCreation(box), ShowCreation(braces_rectangle_x_y_0))
- self.add_fixed_orientation_mobjects(braces_rectangle_x_y_0_text)
- self.play(ShowCreation(braces_rectangle_y_z_1))
- self.add_fixed_orientation_mobjects(braces_rectangle_y_z_1_text)
- self.play(ShowCreation(braces_rectangle_x_z_2))
- self.add_fixed_orientation_mobjects(braces_rectangle_x_z_2_text)
- self.wait(2)
-
- self.move_camera(phi=60* DEGREES,theta=80*DEGREES)
- self.add_fixed_in_frame_mobjects(box_area_func)
- self.play(Write(box_area_func))
- self.wait()
-
-
- self.play(ReplacementTransform(box_area_func,box_area_func_2))
- self.add_fixed_in_frame_mobjects(box_area_func_2)
-
-
- self.wait(3)
\ No newline at end of file
--
cgit
From acfcd90d303bb7f1e4cebcc4029c8382e4f89843 Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Fri, 3 Jul 2020 19:55:33 +0530
Subject: Add files via upload
---
.../file1_multivar_func_examples.py | 148 +++++++++++++++++++++
1 file changed, 148 insertions(+)
create mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/file1_multivar_func_examples.py
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/file1_multivar_func_examples.py b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/file1_multivar_func_examples.py
new file mode 100644
index 0000000..c15cdfb
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/file1_multivar_func_examples.py
@@ -0,0 +1,148 @@
+from manimlib.imports import *
+
+class Examples1(GraphScene):
+ def construct(self):
+
+ rectangle = Rectangle(height = 3, width = 4, color = GREEN)
+ rectangle_area_func = TexMobject("Area", "=", "f(", "Length", ",", "Breadth", ")").scale(0.6)
+ rectangle_area_func[0].set_color(RED_C)
+ rectangle_area_func[2].set_color(ORANGE)
+ rectangle_area_func[3].set_color(YELLOW_C)
+ rectangle_area_func[5].set_color(BLUE_C)
+ rectangle_area_func[6].set_color(ORANGE)
+
+
+ rectangle_area = TexMobject("Area", "=", "Length", "\\times", "Breadth").scale(0.6)
+ rectangle_area[0].set_color(RED_C)
+ rectangle_area[2].set_color(YELLOW_C)
+ rectangle_area[4].set_color(BLUE_C)
+
+
+ triangle = Polygon(np.array([-3,-1.5,0]), np.array([2,-1.5,0]), np.array([2,1.5,0]), np.array([-3,-1.5,0]), color = PURPLE)
+
+ triangle_area_func = TexMobject("Area", "=", "f(", "Base", ",", "Height", ")").scale(0.6).move_to(1*DOWN)
+ triangle_area_func[0].set_color(RED_C)
+ triangle_area_func[2].set_color(ORANGE)
+ triangle_area_func[3].set_color(YELLOW_C)
+ triangle_area_func[5].set_color(BLUE_C)
+ triangle_area_func[6].set_color(ORANGE)
+
+ triangle_area = TexMobject("Area", "=", "\\frac{1}{2}", "\\times", "Base", "\\times", "Height").scale(0.6).move_to(1*DOWN)
+ triangle_area[0].set_color(RED_C)
+ triangle_area[2].set_color(GREEN_C)
+ triangle_area[4].set_color(YELLOW_C)
+ triangle_area[6].set_color(BLUE_C)
+
+
+
+ braces_rect1 = Brace(rectangle, LEFT)
+ eq_text1 = braces_rect1.get_text("Length").set_color(YELLOW_C)
+ braces_rect2 = Brace(rectangle, UP)
+ eq_text2 = braces_rect2.get_text("Breadth").set_color(BLUE_C)
+
+
+ braces_triangle_height = Brace(triangle, RIGHT)
+ braces_triangle_height_text = braces_triangle_height.get_text("Height").set_color(BLUE_C)
+
+ braces_triangle_base = Brace(triangle, DOWN)
+ braces_triangle_base_text = braces_triangle_base.get_text("Base").set_color(YELLOW_C)
+
+
+ self.play(ShowCreation(rectangle))
+ self.wait(1)
+ self.play(GrowFromCenter(braces_rect1),Write(eq_text1),GrowFromCenter(braces_rect2),Write(eq_text2))
+ self.wait(1)
+ self.play(Write(rectangle_area_func))
+ self.wait(1)
+ self.play(Transform(rectangle_area_func, rectangle_area))
+ self.wait(1)
+ self.play(FadeOut(braces_rect1),FadeOut(eq_text1),FadeOut(braces_rect2),FadeOut(eq_text2),FadeOut(rectangle_area_func))
+
+
+ self.play(Transform(rectangle, triangle))
+ self.wait(1)
+ self.play(GrowFromCenter(braces_triangle_height),Write(braces_triangle_height_text))
+ self.wait(1)
+ self.play(GrowFromCenter(braces_triangle_base),Write(braces_triangle_base_text))
+ self.wait(1)
+ self.play(Write(triangle_area_func))
+ self.wait(1)
+ self.play(Transform(triangle_area_func, triangle_area))
+ self.wait(1)
+ self.play(FadeOut(braces_triangle_height),FadeOut(braces_triangle_height_text),FadeOut(braces_triangle_base),FadeOut(braces_triangle_base_text),FadeOut(triangle_area_func))
+ self.wait(1)
+
+
+
+
+class Examples2(ThreeDScene):
+ def construct(self):
+ axes = ThreeDAxes()
+
+ rectangle_x_y_0 = Polygon(np.array([-1,-2,0]),np.array([-1,2,0]),np.array([1,2,0]),np.array([1,-2,0]),np.array([-1,-2,0]), color = RED_E, fill_color = RED_C, fill_opacity = 0.1)
+ rectangle_x_y_3 = Polygon(np.array([-1,-2,3]),np.array([-1,2,3]),np.array([1,2,3]),np.array([1,-2,3]),np.array([-1,-2,3]), color = RED_E, fill_color = RED_C, fill_opacity = 0.1)
+
+ rectangle_y_z_1 = Polygon(np.array([1,-2,3]),np.array([1,2,3]),np.array([1,2,0]),np.array([1,-2,0]),np.array([1,-2,3]), color = RED_E, fill_color = RED_C, fill_opacity = 0.1)
+ rectangle_y_z_minus_1 = Polygon(np.array([-1,-2,3]),np.array([-1,2,3]),np.array([-1,2,0]),np.array([-1,-2,0]),np.array([-1,-2,3]), color = RED_E, fill_color = RED_C, fill_opacity = 0.1)
+
+ rectangle_x_z_2 = Polygon(np.array([1,2,3]),np.array([-1,2,3]),np.array([-1,2,0]),np.array([1,2,0]),np.array([1,2,3]), color = RED_E, fill_color = RED_C, fill_opacity = 0.1)
+ rectangle_x_z_minus_2 = Polygon(np.array([1,-2,3]),np.array([-1,-2,3]),np.array([-1,-2,0]),np.array([1,-2,0]),np.array([1,-2,3]), color = RED_E, fill_color = RED_C, fill_opacity = 0.1)
+
+ box = VGroup(rectangle_x_y_0, rectangle_x_y_3, rectangle_y_z_1, rectangle_y_z_minus_1, rectangle_x_z_2, rectangle_x_z_minus_2)
+
+ braces_rectangle_x_y_0 = Line(np.array([1,2,0]), np.array([1,-2,0]), color = BLUE_C)
+ braces_rectangle_x_y_0_text = TextMobject("Length").set_color(BLUE_C).move_to(np.array([2,-1,0]))
+
+ braces_rectangle_y_z_1 = Line(np.array([1,2,0]), np.array([1,2,3]), color = YELLOW_C)
+ braces_rectangle_y_z_1_text = TextMobject("Height").set_color(YELLOW_C).move_to(np.array([2,3.8,2]))
+
+ braces_rectangle_x_z_2 = Line(np.array([1,2,3]), np.array([-1,2,3]), color = PURPLE)
+ braces_rectangle_x_z_2_text = TextMobject("Breadth").set_color(PURPLE).move_to(np.array([0,3.8,3.3]))
+
+ box_area_func = TexMobject("Area =", "f(", "Length", ",", "Breadth", ",", "Height", ")").move_to(4*LEFT+3.5*UP).scale(0.6)
+ box_area_func[0].set_color(GREEN_C)
+ box_area_func[1].set_color(ORANGE)
+ box_area_func[2].set_color(BLUE_C)
+ box_area_func[4].set_color(PURPLE)
+ box_area_func[6].set_color(YELLOW_C)
+ box_area_func[7].set_color(ORANGE)
+
+ box_area_func_2 = TexMobject("Area =", "Length", "\\times", "Breadth", "\\times", "Height").move_to(4*LEFT+3.5*UP).scale(0.6)
+ box_area_func_2[0].set_color(GREEN_C)
+ box_area_func_2[1].set_color(BLUE_C)
+ box_area_func_2[3].set_color(PURPLE)
+ box_area_func_2[5].set_color(YELLOW_C)
+
+
+ self.set_camera_orientation(phi=70 * DEGREES, theta = 45*DEGREES)
+
+ self.add(axes)
+
+ axis = TextMobject(r"X",r"Y",r"Z")
+ axis[0].move_to(6*RIGHT)
+ axis[1].move_to(6*UP)
+ axis[2].move_to(3.7*UP)
+
+ self.add_fixed_in_frame_mobjects(axis[2])
+ self.add_fixed_orientation_mobjects(axis[0])
+ self.add_fixed_orientation_mobjects(axis[1])
+
+ self.play(ShowCreation(box), ShowCreation(braces_rectangle_x_y_0))
+ self.add_fixed_orientation_mobjects(braces_rectangle_x_y_0_text)
+ self.play(ShowCreation(braces_rectangle_y_z_1))
+ self.add_fixed_orientation_mobjects(braces_rectangle_y_z_1_text)
+ self.play(ShowCreation(braces_rectangle_x_z_2))
+ self.add_fixed_orientation_mobjects(braces_rectangle_x_z_2_text)
+ self.wait(2)
+
+ self.move_camera(phi=60* DEGREES,theta=80*DEGREES)
+ self.add_fixed_in_frame_mobjects(box_area_func)
+ self.play(Write(box_area_func))
+ self.wait()
+
+
+ self.play(ReplacementTransform(box_area_func,box_area_func_2))
+ self.add_fixed_in_frame_mobjects(box_area_func_2)
+
+
+ self.wait(3)
\ No newline at end of file
--
cgit
From 90e3c80b13fa66693a03858999644982157f06b2 Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Fri, 3 Jul 2020 19:56:01 +0530
Subject: Delete file1_multivar_func_examples.gif
---
.../gifs/file1_multivar_func_examples.gif | Bin 1440511 -> 0 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/gifs/file1_multivar_func_examples.gif
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/gifs/file1_multivar_func_examples.gif b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/gifs/file1_multivar_func_examples.gif
deleted file mode 100644
index 43c3a42..0000000
Binary files a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/gifs/file1_multivar_func_examples.gif and /dev/null differ
--
cgit
From 6cbec5e50a290209cc5e1d619de81df32f4b83ca Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Fri, 3 Jul 2020 19:56:31 +0530
Subject: Add files via upload
---
.../gifs/file1_multivar_func_examples.gif | Bin 0 -> 1453898 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/gifs/file1_multivar_func_examples.gif
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/gifs/file1_multivar_func_examples.gif b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/gifs/file1_multivar_func_examples.gif
new file mode 100644
index 0000000..d078fb9
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/gifs/file1_multivar_func_examples.gif differ
--
cgit
From 05080cd0751a9ebd7acf9c94790461038aa9a069 Mon Sep 17 00:00:00 2001
From: Saarth Deshpande
Date: Sat, 4 Jul 2020 02:13:27 +0530
Subject: tnb, curvature interpretation
---
.../arc-length-and-curvature/file1_arc_length.py | 319 +--------------------
.../file2_simple_visualization.py | 60 ++--
.../file4_curvature_interpretation.py | 86 +++++-
.../file3_tnb_frame_manim.py | 112 +++++++-
4 files changed, 233 insertions(+), 344 deletions(-)
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_arc_length.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_arc_length.py
index 75c19aa..e295c7a 100644
--- a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_arc_length.py
+++ b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_arc_length.py
@@ -1,325 +1,32 @@
-# Contribution creidts: Somnath Pandit
-
from manimlib.imports import *
-class LineIntegrationAsSum(GraphScene):
+class arcl(GraphScene):
CONFIG = {
"x_min" : 0,
"x_max" : 10,
"y_min" : 0,
"y_max" : 6,
- "graph_origin": ORIGIN+5*LEFT+3*DOWN,
+ "graph_origin": ORIGIN,
"x_axis_width": 10,
"y_axis_height": 6 ,
"x_tick_frequency": 2,
"y_tick_frequency": 2,
"Func":lambda x : 1+x**1.3*np.exp(-.12*(x-2)**2)*np.sin(x/4),
- "a": 1 ,"b": 9, "n": 15,
}
-
def construct(self):
- X = RIGHT*self.x_axis_width/(self.x_max- self.x_min)
- Y = UP*self.y_axis_height/(self.y_max- self.y_min)
- self.X=X ;self.Y=Y
-
- self.setup_axes(animate=False)
-
-
- curve=self.get_graph(
- self.Func,
- x_min=self.a,
- x_max=self.b,
- )
- curve.set_color([BLACK,BLUE,BLUE,BLUE,BLACK])
- curve_label= self.get_graph_label(
- curve,
- label="\\text{Curve for integration:}",
- x_val=4,
- direction=UR,
- buff=.6,
- color=BLUE
- )
- self.curve=curve
- self.curve_label=curve_label
-
- self.get_vector_field()
-
-
- self.play(ShowCreation(VGroup(curve,curve_label)))
- self.wait(.6)
- self.break_in_arcs()
- self.show_the_sum()
-
- self.wait(2)
-
-
- def get_vector_field(self):
- func = lambda v: np.array([
- v[0], # x
- -v[1], # y
- 0 # z
- ])
- vector_field= VectorField(
- func,
- delta_x=1,
- delta_y=1,
- colors=[GREEN_A,GREEN_C],
- length_func= lambda norm: .8*sigmoid(norm),
- vector_config={
- "stroke_width": 2
- }
- )
-
- self.vector_field= vector_field
-
-
- def break_in_arcs(self):
-
- self.write_about_breaking()
-
- dl=0.8
- self.get_breakers(dl)
- self.wait(2)
- self.play(FadeOut(self.upto_break_text))
- self.dl=dl
-
- def write_about_breaking(self):
- breaking_text=TextMobject("\\texttt{is broken}"," into small ", "subarcs")
- breaking_text.set_color_by_tex_to_color_map({
- "broken":RED,"subarcs": BLUE
- })
- breaking_text.next_to(self.curve_label,DOWN)
- breaking_text.align_to(self.curve_label,LEFT)
- self.play(
- Write(breaking_text)
- )
-
- self.upto_break_text=VGroup(
- self.curve_label,
- breaking_text,
- )
-
- def get_breakers(self,dl):
- point=self.a
- points=[]
- while point<(self.b-dl) :
- start=point
- end=point+dl
- points += [end]
- breaker=Line(
- self.input_to_graph_point(start,self.curve),
- self.input_to_graph_point(end,self.curve),
- stroke_width=2,
- color=RED,
- )
- breaker.rotate(PI/2).scale(.5)
-
- point=end
- self.play(FadeIn(breaker),run_time=.2)
- # self.add(breaker)
-
- del points[-1]
- self.points=points
-
-
- def show_the_sum(self):
- at_any_points_text=TextMobject("At an arbitrary ","point", " in each ", "subarc")
- at_any_points_text.set_color_by_tex_to_color_map({
- "point":YELLOW , "subarc": BLUE
- })
- at_any_points_text.to_edge(TOP,buff=SMALL_BUFF)
-
- evaluate_text=TextMobject("$\\vec F(x,y)$ ", "is evaluated").next_to(at_any_points_text,DOWN)
- evaluate_text.set_color_by_tex("$\\vec F(x,y)$",ORANGE)
-
- multiply_text=TextMobject("...is multiplied with ","$\\Delta s_i$")
- multiply_text.set_color_by_tex("\\Delta s_i", BLUE)
- multiply_text.next_to(at_any_points_text,DOWN)
-
-
-
- self.at_any_points_text=at_any_points_text
- self.evaluate_text=evaluate_text
- self.multiply_text=multiply_text
-
- dots=[]
- for point in self.points:
-
- dot=Dot(
- point=self.input_to_graph_point(point,self.curve),
- radius= .7*DEFAULT_DOT_RADIUS,
- stroke_width= 0,
- fill_opacity= 1.0,
- color= YELLOW,
- )
- dots+=[dot]
-
- self.play(
- Write(at_any_points_text),
- FadeIn(VGroup(*dots)),run_time=1.5
- )
- self.dots=dots
-
- self.wait()
- self.show_the_dot_product()
- self.multiply_with_ds()
- self.construct_equation()
-
-
- def show_the_dot_product(self):
- index=-(len(self.points)//3)
- self.index=index
-
- dot=self.dots[index]
-
-
- dot_prod_text=TextMobject("Dot product of ", "$\\vec F(x_i,y_i)$", " and ","$\\vec T(x_i,y_i)$")
- dot_prod_text.set_color_by_tex_to_color_map({
- "\\vec F(x_i,y_i)":ORANGE ,
- "\\vec T(x_i,y_i)": "#DC75CD" ,
- })
- dot_prod_text.to_edge(TOP,buff=SMALL_BUFF)
-
-
- point_coord=TextMobject("$(x_i,y_i)$",color=YELLOW)
- point_coord.next_to(dot,DL,buff=.01).scale(.8)
-
- func_val=TextMobject("$\\vec F(x_i,y_i)$",color=ORANGE)
- func_val.next_to(dot,UR).scale(.8)
-
- self.dot_prod_text=dot_prod_text
- self.func_val=func_val
-
- dot.set_color(ORANGE).scale(1.2)
-
-
- self.play(FadeIn(VGroup(point_coord,dot)))
- self.play(Write(self.evaluate_text))
- self.wait(1)
- self.play(FadeOut(self.vector_field))
- self.get_vector_and_tangent()
- self.dot_product()
-
-
- self.wait(2)
- self.remove(point_coord)
-
-
- def get_vector_and_tangent(self):
- dot=self.dots[self.index]
- self.show_specific_vectors(dot)
- self.play(Write(self.func_val))
- self.wait(1)
- self.show_tangent(dot)
- self.play(FadeIn(VGroup(*[
- dot.set_color(ORANGE).scale(1.4)
- for dot in self.dots ]
- )))
-
-
- def show_specific_vectors(self,dots):
- for dot in dots:
- vector=self.vector_field.get_vector(dot.get_center())
- vector.set_color(ORANGE)
-
- self.play(Write(vector),run_time=.2)
-
-
- def show_tangent(self,dot):
- tangent_sym=TextMobject("$\\vec T(x_i,y_i)$",color="#DC75CD").scale(.8)
- x=dot.get_center()
- angle=self.angle_of_tangent(
- self.point_to_coords(x)[0],
- self.curve,
- dx=0.01
- )
- vect = Vector().rotate(angle,about_point=x)
- vect.set_color("#DC75CD")
- tangent=vect.next_to(x,DR,buff=0)
- tangent_sym.next_to(tangent,DOWN,buff=.1)
- self.play(Write(VGroup(tangent,tangent_sym)))
-
- self.tangent_sym=tangent_sym
-
- def dot_product(self):
-
- dot_sym=Dot().next_to(self.func_val,RIGHT)
-
- self.play(FadeOut(VGroup(
- self.at_any_points_text,
- self.evaluate_text
- )))
- self.play(Write(self.dot_prod_text))
- self.play(
- FadeIn(dot_sym),
- ApplyMethod(
- self.tangent_sym.next_to,
- dot_sym, RIGHT
- ))
-
- self.dot_sym=dot_sym
-
- def multiply_with_ds(self):
- self.get_ds()
-
- self.play(GrowFromCenter(self.ds_brace_group))
- self.wait(2)
- self.play(Write(self.multiply_text))
- self.play(ApplyMethod(
- self.ds_brace_label.next_to,
- self.tangent_sym, RIGHT,buff=.15
- ))
-
-
-
- def get_ds(self):
- p1= self.dots[self.index]
- p2= self.dots[self.index+1]
- ds_brace=Brace(VGroup(p1,p2),DL)
- ds_brace.move_to(p1,UR)
- ds_brace_label=ds_brace.get_text("$\Delta s_i$", buff = .05)
- ds_brace_label.set_color(BLUE)
- self.ds_brace=ds_brace
- self.ds_brace_label=ds_brace_label
- self.ds_brace_group=VGroup(ds_brace,ds_brace_label)
-
-
- def construct_equation(self):
- sum_up_text=TextMobject("and"," summed ", "for all `i's")
- sum_up_text.set_color_by_tex("summed",PURPLE_A)
- sum_up_text.next_to(self.multiply_text,DOWN,buff=MED_SMALL_BUFF)
- sum_up_text.shift(LEFT)
-
- sum_eqn=TextMobject("$$\\sum_i^{ } $$").set_color(PURPLE_A)
- sum_eqn.move_to(self.graph_origin+6.5*self.X+4*self.Y)
-
- line_integral_text=TextMobject("The"," line ","integral's value is: ").to_edge(TOP,buff=MED_SMALL_BUFF)
- line_integral_text.set_color_by_tex("line",BLUE_C)
- approx=TextMobject("$\\approx$",color=RED).next_to(sum_eqn,LEFT)
- multipled=VGroup(
- self.func_val,
- self.dot_sym,
- self.tangent_sym,
- self.ds_brace_label
- )
-
+ self.setup_axes(hideaxes = True)
+ def curve_(x):
+ return 3 - (3653*x**2)/5292 + (2477*x**3)/31752 + (13*x**4)/784 - (17*x**5)/5292 + (17*x**6)/63504
- self.play(Write(sum_up_text))
- self.show_specific_vectors(self.dots)
- self.play(FadeIn(sum_eqn))
- self.play(ApplyMethod(
- multipled.next_to,sum_eqn,RIGHT
- ))
- self.wait()
- self.play(FadeOut(VGroup(
- self.dot_prod_text,
- self.multiply_text,
- sum_up_text
- )))
- self.play(Write(line_integral_text))
- self.play(FadeIn(approx))
+ curve = FunctionGraph(curve_, x_min=-2, x_max=6, stroke_width = 2, color = BLUE).scale(0.1).move_to(ORIGIN)
+ lines = [Line(length = 0.05, color = RED) for i in range(10)]
+ lines[0].move_to(np.array([curve_(-2),-2, 0]))
-#uploaded by Somnath Pandit.FSF2020_Line Integrals
+ # self.play(FadeIn(curve))
+ # self.wait(2)
+ self.play(ApplyMethod(curve.scale, 10))
+ self.play(FadeIn(VGroup(*lines)))
+ self.wait(5)
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file2_simple_visualization.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file2_simple_visualization.py
index 45058d7..05cad80 100644
--- a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file2_simple_visualization.py
+++ b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file2_simple_visualization.py
@@ -1,8 +1,8 @@
from manimlib.imports import *
-class randomcurve(GraphScene):
+class a(GraphScene):
CONFIG = {
- "x_min": -4,
+ "x_min": -3,
"x_max": 6,
"y_min": -6,
"y_max": 10,
@@ -10,12 +10,15 @@ class randomcurve(GraphScene):
}
def construct(self):
intro = TextMobject('Consider the following curve.')
- mid = TextMobject(r'Notice how the direction of the unit tangent vectors\\changes with respect to the arc length.')
- outro = TextMobject(r'The rate of change of unit tangents with \\ respect to the arc length $ds$ is called curvature.\\Mathematically, curvature $ = k = \left|{\frac{dT}{ds}}\right|$')
+ mid = TextMobject(r'Notice how the direction of the unit tangent vector\\changes with respect to the arc length.')
+ outro = TextMobject(r'The rate of change of unit tangent with \\ respect to the arc length $ds$ is called curvature.\\Mathematically, curvature $ = k = \left|{\frac{dT}{ds}}\right|$')
XTD = self.x_axis_width/(self.x_max- self.x_min)
YTD = self.y_axis_height/(self.y_max- self.y_min)
+ circle = Circle(radius = 0.95, color = GRAY, fill_opacity = 0.2, fill_color = RED)
+ circle.set_stroke(width = 0.1)
+
tgt1 = Arrow((-2.2*XTD,-0.5*YTD,0),(-1*XTD,1,0))
tgt2 = Arrow((-1.2*XTD, 1.93*YTD,0),(0*XTD,1.6,0)).scale(1.2)
tgt3 = Arrow((-0.3*XTD,3*YTD, 0), (1.5*XTD, 3*YTD,0))
@@ -40,30 +43,49 @@ class randomcurve(GraphScene):
ds_text = TextMobject(r'$ds$').next_to(ds, UP, buff = 0.1).shift(1.3*LEFT)
self.setup_axes(hideaxes=True)
- graphobj = self.get_graph(self.curve)
+
+ def curve(x):
+ return 3 - (3653*x**2)/5292 + (2477*x**3)/31752 + (13*x**4)/784 - (17*x**5)/5292 + (17*x**6)/63504
+
+ # parabola_x_out = FunctionGraph(curve, x_min=-2, x_max=6, stroke_width = 2, color = BLUE)
+ parabola_x_out = self.get_graph(curve)
+
+ dot_x = Dot().rotate(PI/2).set_color(YELLOW_E)
+ alpha_x = ValueTracker(-2)
+ vector_x = self.get_tangent_vector(alpha_x.get_value(),parabola_x_out,scale=1.5)
+ dot_x.add_updater(lambda m: m.move_to(vector_x.get_center()))
+ vector_x.add_updater(
+ lambda m: m.become(
+ self.get_tangent_vector(alpha_x.get_value()%1,parabola_x_out,scale=1.5)
+ )
+ )
+
self.play(FadeIn(intro))
self.wait(2)
self.play(FadeOut(intro))
self.setup_axes(hideaxes=False)
- self.play(ShowCreation(graphobj), FadeIn(dots), FadeIn(ds), FadeIn(ds_text), FadeIn(arc))
- self.wait(1)
- self.play(FadeOut(self.axes), FadeOut(arc), FadeOut(graphobj),FadeIn(mid), FadeOut(dots), FadeOut(ds), FadeOut(ds_text))
+ self.play(ShowCreation(parabola_x_out), FadeIn(dots), FadeIn(ds), FadeIn(ds_text), FadeIn(arc))
+ self.wait(2)
+ self.play(FadeOut(self.axes), FadeOut(arc), FadeOut(parabola_x_out),FadeIn(mid), FadeOut(dots), FadeOut(ds), FadeOut(ds_text))
self.wait(3)
self.play(FadeOut(mid))
- self.play(FadeIn(self.axes), FadeIn(graphobj), FadeIn(dots))
-
- tangents = [tgt1, tgt2, tgt3, tgt4, tgt5, tgt6, tgt7]
- for tangent in tangents:
- self.play(ShowCreation(tangent), run_time = 0.2)
- self.wait(1)
- tangents = VGroup(*tangents)
- self.play(FadeOut(self.axes), FadeOut(graphobj), FadeOut(tangents), FadeOut(dots))
- self.wait(1)
+ self.play(FadeIn(self.axes), FadeIn(parabola_x_out), FadeIn(dots))
+ self.add(vector_x)
+ self.play(alpha_x.increment_value, 1, run_time=8, rate_func=linear)
+ self.remove(vector_x)
+ self.play(FadeOut(VGroup(*[self.axes, dots, parabola_x_out])))
self.play(FadeIn(outro))
self.wait(3)
self.play(FadeOut(outro))
self.wait(1)
- def curve(self, x):
- return 3 - (3653*x**2)/5292 + (2477*x**3)/31752 + (13*x**4)/784 - (17*x**5)/5292 + (17*x**6)/63504
+
+
+ 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)
+ unit_vector = reference_line.get_unit_vector() * scale
+ vector = Arrow(coord_i , coord_i + unit_vector, color = YELLOW, buff=0)
+ return vector
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file4_curvature_interpretation.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file4_curvature_interpretation.py
index d8dd0a4..128fc17 100644
--- a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file4_curvature_interpretation.py
+++ b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file4_curvature_interpretation.py
@@ -1,12 +1,55 @@
from manimlib.imports import *
-class interpretation(Scene):
+class interpretation(ZoomedScene):
+ CONFIG = {
+ "zoomed_display_height": 3,
+ "zoomed_display_width": 3,
+ "zoom_factor": 0.15,
+ "zoomed_display_center": ORIGIN + 4*LEFT + DOWN,
+ }
def construct(self):
- tgt = Vector((1, 2, 0), color = YELLOW)
+
+ tgt = Vector((1, 2, 0), color = YELLOW).shift(0.005*RIGHT + 0.007*DOWN)
+ dot = Dot(tgt.get_start(),color = RED)
+ curve = ParametricFunction(
+ lambda t: np.array([
+ 2*(t**2),
+ 4*t,
+ 0
+ ]), t_min = -5, t_max = 5
+ ).scale(0.3).move_to(ORIGIN + 4*RIGHT).rotate(6*DEGREES)
+
+ ds = ParametricFunction(
+ lambda t: np.array([
+ 2*(t**2),
+ 4*t,
+ 0
+ ]), t_min = 0, t_max = 0.05, color = GREEN_SCREEN
+ ).scale(0.9).shift(3.09*LEFT).rotate(-27.5*DEGREES).move_to(ORIGIN).shift(0.07*UP + 0.05*RIGHT).set_stroke(width=20)
+
+ dsl = TextMobject(r'$ds$', color = GREEN_SCREEN).scale(0.2).next_to(ds, RIGHT, buff = 0)
+
+
tgtText = TextMobject(r'$r\prime (t)$').next_to(tgt, UP, buff = 0).scale(0.7)
tgt2 = DashedLine((0,0,0),(1, 2, 0), color = GRAY).shift(DOWN + 2*RIGHT)
+ circle = Circle(radius = 0.9, color = GREEN_SCREEN).shift(0.85*RIGHT + 0.38*DOWN)
+ circle.set_stroke(opacity = 1)
+ dl = DashedLine(circle.get_center(), dot.get_center())
+ dltext = TextMobject(r'$R = 2.795$').scale(0.5).next_to(circle.get_center(), DOWN, buff = 0.1)
+
+ main = TextMobject(r'r(t) = $\left\langle t^{2}, 2t, 0 \right\rangle\quad r\prime (t) = \left\langle 2t, 2, 0 \right\rangle\quad$ \\ $r\prime\prime (t) = \left\langle 2, 0, 0 \right\rangle$').scale(0.7).shift(3*UP + 3*LEFT)
+ main2 = TextMobject(r'Curvature at an arbitrary point \\ say r(t = 0.5) can be given as: \\ $\kappa = \frac{1}{R} = \frac{1}{2.795} = 0.357$').scale(0.7).shift(3.5*LEFT)
+ main3 = TextMobject(r'The ', 'tangent', r' and ', 'normal', r' vectors \\ can be represented as:').scale(0.7).shift(3.5*LEFT)
+ main3.set_color_by_tex_to_color_map({
+ "tangent": YELLOW,
+ "normal": BLUE
+ })
+ main4 = TextMobject(r'These vectors travel along \\ a small interval ', r'$ds$').scale(0.7).shift(1.5*UP + 3*LEFT)
+ main4.set_color_by_tex_to_color_map({
+ "$ds$": GREEN_SCREEN
+ })
- nm = Vector((2, -1, 0), color = BLUE)
+ nm = Vector((2, -1, 0), color = BLUE).shift(0.005*RIGHT + 0.007*DOWN)
nmText = TextMobject(r'$r\prime\prime (t)$').next_to(nm, DOWN+RIGHT, buff = 0).scale(0.7)
nm2 = DashedLine((0,0,0),(2, -1, 0), color = GRAY).shift(2*UP + RIGHT)
square = Square(fill_color = WHITE, fill_opacity = 0.2).rotate(63*DEGREES).shift(0.5*UP +1.5*RIGHT).scale(1.1)
@@ -14,20 +57,41 @@ class interpretation(Scene):
arrow = CurvedArrow(square.get_center() + np.array([2,1,0]), square.get_center() + np.array([0.5,0,0]))
arrowText = TextMobject(r'$r\prime (t)\times r\prime\prime (t)$').next_to(arrow.get_start(), DOWN+1*RIGHT, buff = 0).scale(0.7)
- text1 = TextMobject(r'$\left|\frac{dT}{ds}\right| = \frac{\left|\frac{dT}{dt}\right|}{\left|\frac{ds}{dt}\right|}$').shift(UP+3*LEFT)
- text2 = TextMobject(r'$\left|\frac{dT}{ds}\right| = \frac{\frac{r\prime\prime (t)}{\left| r\prime (t)\right|}\times\frac{r\prime (t)}{\left| r\prime (t)\right|}}{\left|r\prime (t)\right|}$').next_to(text1, DOWN, buff = 0.1)
+ text1 = TextMobject(r'$\left|\frac{dT}{ds}\right| = \frac{\left|\frac{dT}{dt}\right|}{\left|\frac{ds}{dt}\right|}$').shift(UP+3*LEFT).scale(0.7)
+ text2 = TextMobject(r'$\left|\frac{dT}{ds}\right| = \frac{\frac{r\prime\prime (t)}{\left| r\prime (t)\right|}\times\frac{r\prime (t)}{\left| r\prime (t)\right|}}{\left|r\prime (t)\right|}$').next_to(text1, DOWN, buff = 0.1).scale(0.7)
+ text3 = TextMobject(r'$= \frac{4}{(4t^{2} + 4)^{\frac{3}{2}}}$ \\ $= \frac{1}{2\sqrt{(1 + (0.5)^{2})^{3}}}$').next_to(text2, DOWN, buff = 0.1).scale(0.7)
+ text4 = TextMobject(r'$ = 0.357$').scale(0.7).next_to(text3, DOWN, buff = 0.2)
unit = VGroup(*[tgt, tgt2, nm, nm2])
- # self.play(FadeIn(VGroup(*[tgt, tgt2, nm, nm2, nmText, tgtText, square, arrow, arrowText])))
tgt2text = TextMobject(r'$\frac{r\prime (t)}{\left| r\prime (t)\right|}$').shift(1.1*UP).scale(0.7).rotate(63*DEGREES )
nm2text = TextMobject(r'$\frac{r\prime\prime (t)}{\left| r\prime (t)\right|}$').scale(0.7).shift(0.7*RIGHT+0.8*DOWN).rotate(-25*DEGREES)
unit2 = unit.copy().scale(0.5).shift(0.75*LEFT+0.25*DOWN)
- self.play(FadeIn(VGroup(*[tgt, tgtText])))
+ self.play(FadeIn(curve), FadeIn(main))
+ self.wait(1)
+ self.play(ApplyMethod(curve.scale, 3), ApplyMethod(curve.shift, ORIGIN + 3.31*RIGHT))
+ # self.wait(2)
+ self.play(FadeIn(main2), FadeIn(dot))
+ self.play(FadeIn(circle), FadeIn(dl), FadeIn(dltext))
+ self.wait()
+ self.play(ReplacementTransform(main2, main3), FadeOut(circle), FadeOut(dl), FadeOut(dltext), FadeIn(VGroup(*[tgt, tgtText])))
self.wait(1)
self.play(FadeIn(VGroup(*[nm, nmText])))
self.wait(1)
- self.play(FadeIn(VGroup(*[tgt2, nm2])))
+ self.remove(dot)
+ self.setup()
+ #self.camera_frame.set_width(4)
+ self.activate_zooming(animate = True)
+ self.play(FadeIn(ds), FadeIn(dsl), FadeOut(main3))
+ self.wait(1)
+ self.play(FadeIn(main4))
+ self.play(ApplyMethod(tgt.shift, 0.16*UP + 0.09*RIGHT), ApplyMethod(nm.shift, 0.16*UP + 0.09*RIGHT), run_time = 5)
+ self.wait(1)
+ self.play(FadeOut(ds), FadeOut(dsl), FadeOut(main4), FadeOut(self.zoomed_display, run_time = 1), FadeOut(self.zoomed_camera.frame, run_time = 1))
+ # tgt = tgt.shift(0.16*DOWN + 0.08*LEFT)
+ # nm = nm.shift(0.16*DOWN + 0.08*LEFT)
+ self.play(ApplyMethod(tgt.shift, 0.16*DOWN + 0.09*LEFT, run_time = 1), ApplyMethod(nm.shift, 0.16*DOWN + 0.09*LEFT, run_time = 1))
+ self.play(FadeIn(dot), FadeIn(VGroup(*[tgt2, nm2])))
self.wait(1)
self.play(FadeIn(VGroup(*[square, arrow, arrowText])))
self.wait(1)
@@ -38,5 +102,9 @@ class interpretation(Scene):
self.play(FadeIn(text1))
self.wait(1)
self.play(FadeIn(text2))
+ self.wait(1)
+ self.play(FadeIn(text3))
+ self.wait(1)
+ self.play(FadeIn(text4))
self.wait(2)
- self.play(FadeOut(VGroup(*[tgt2text, nm2text, text1, text2, tgt, tgtText,nm, nmText,tgt2, nm2,square, arrow, arrowText,unit2])))
+ self.play(FadeOut(VGroup(*[main, curve, dot, tgt2text, nm2text, text1, text2, text3, text4, tgt, tgtText,nm, nmText,tgt2, nm2,square, arrow, arrowText,unit2])))
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])))
--
cgit
From 975a74e11015394cd5ccfdd9edb2bd4863273cac Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Sat, 4 Jul 2020 12:39:33 +0530
Subject: Delete file4_partial_deriv_example.py
---
.../file4_partial_deriv_example.py | 246 ---------------------
1 file changed, 246 deletions(-)
delete mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/file4_partial_deriv_example.py
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/file4_partial_deriv_example.py b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/file4_partial_deriv_example.py
deleted file mode 100644
index 5712a62..0000000
--- a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/file4_partial_deriv_example.py
+++ /dev/null
@@ -1,246 +0,0 @@
-from manimlib.imports import *
-
-class PartialDerivX(ThreeDScene):
- def construct(self):
- axes = ThreeDAxes()
-
- paraboloid = ParametricSurface(
- lambda u, v: np.array([
- 2*np.sin(u)*np.cos(v),
- 2*np.sin(u)*np.sin(v),
- -2*2*np.sin(u)*np.sin(u)+2
- ]),u_min=0,u_max=PI/2,v_min=0,v_max=2*PI,checkerboard_colors=[PINK, PURPLE],
- resolution=(15, 32)).scale(1)
-
- paraboloid_copy = paraboloid.copy()
-
-
- paraboloid_x = ParametricSurface(
- lambda u, v: np.array([
- 2*np.sin(u)*np.cos(v),
- 2*np.sin(u)*np.sin(v),
- -2*2*np.sin(u)*np.sin(u)+2
- ]),u_min=0,u_max=PI/2,v_min=PI,v_max=2*PI,checkerboard_colors=[PINK, PURPLE],
- resolution=(15, 32)).scale(1)
-
-
- parabola =ParametricFunction(
- lambda u : np.array([
- u,
- 0,
- -(u*u) + 2
- ]),color="#006400",t_min=-2,t_max=2,
- )
-
- plane = Polygon(np.array([-2.2,0,-2.5]),np.array([2.2,0,-2.5]),np.array([2.2,0,2.5]),np.array([-2.2,0,2.5]),np.array([-2.2,0,-2.5]), color = GREEN, fill_color = GREEN, fill_opacity = 0.2)
- plane_text = TextMobject(r"$y = 0$", color = GREEN_C).move_to(2*UP + 3*RIGHT)
-
- surface_eqn = TextMobject("Surface", r"$z = 2- x^2 -y^2$", color = PINK).scale(0.6).move_to(np.array([3*LEFT +3*UP]))
- surface_eqn[0].set_color(BLUE_C)
-
- line = Line(np.array([-2,0,0]), np.array([2,0,0]), color = RED_C)
-
-
- self.add(axes)
-
- axis = TextMobject(r"X",r"Y",r"Z")
- axis[0].move_to(6*RIGHT)
- axis[1].move_to(6*UP)
- axis[2].move_to(3.7*UP)
-
- self.add_fixed_in_frame_mobjects(axis[2])
- self.add_fixed_orientation_mobjects(axis[0])
- self.add_fixed_orientation_mobjects(axis[1])
-
-
- self.set_camera_orientation(phi=80 * DEGREES, theta = 0*DEGREES)
-
- self.play(Write(paraboloid))
-
- self.add_fixed_in_frame_mobjects(surface_eqn)
- #self.move_camera(phi=80* DEGREES,theta=95*DEGREES)
- self.move_camera(phi=80* DEGREES,theta=45*DEGREES)
- self.play(ShowCreation(plane))
- self.add_fixed_in_frame_mobjects(plane_text)
- self.wait()
- self.play(ReplacementTransform(paraboloid, paraboloid_x))
- self.play(FadeOut(plane), FadeOut(plane_text))
- self.play(ShowCreation(parabola), ShowCreation(line))
-
- text1 = TextMobject("Moving small", r"$dx$", r"steps").scale(0.6).move_to(3*UP + 3.5*RIGHT).set_color_by_gradient(RED, ORANGE, YELLOW, BLUE, PURPLE)
-
- text2 = TextMobject("Observing change in function, keeping", r"$y$", r"constant").scale(0.6).move_to(2.6*UP + 3.5*RIGHT).set_color_by_gradient(RED, ORANGE, YELLOW, GREEN, BLUE, PURPLE)
-
- slope_text = TexMobject("Slope =", "{\\partial", "f", "\\over", "\\partial", "x}").scale(0.6).move_to(2*UP + 3.5*RIGHT)
- slope_text[0].set_color(BLUE_E)
- slope_text.set_color_by_tex("\\partial",PINK)
- slope_text.set_color_by_tex("f","#006400")
- slope_text[5].set_color(RED_C)
-
- self.add_fixed_in_frame_mobjects(text1, text2)
- self.wait()
- self.add_fixed_in_frame_mobjects(slope_text)
- #add_fixed_orientation_mobjects
-
-
- dot = Dot().rotate(PI/2).set_color(RED_C)
- alpha = ValueTracker(0)
- vector = self.get_tangent_vector(alpha.get_value(),parabola,scale=1.5)
- dot.add_updater(lambda m: m.move_to(vector.get_center()))
- self.play(
- ShowCreation(parabola),
- GrowFromCenter(dot),
- GrowArrow(vector)
- )
- vector.add_updater(
- lambda m: m.become(
- self.get_tangent_vector(alpha.get_value()%1,parabola,scale=1.5)
- )
- )
- self.add(vector,dot)
- self.play(alpha.increment_value, 1, run_time=10, rate_func=linear)
- self.wait()
-
-
- '''
- for i in np.arange(-2,2,0.2):
- self.play(ReplacementTransform(Line(np.array([i,0,0]), np.array([i,0,-i*i + 2]), color = GREEN_C), Line(np.array([i+0.2,0,0]), np.array([i+0.2,0,-(i+0.2)**2 + 2]), color = GREEN_C)))
- #self.wait()
- '''
-
- self.wait()
- self.play(FadeOut(parabola), FadeOut(line), FadeOut(vector), FadeOut(dot), FadeOut(text1), FadeOut(text2), FadeOut(slope_text),FadeOut(surface_eqn))
-
- #self.move_camera(phi=80* DEGREES,theta= 0*DEGREES)
- self.play(ReplacementTransform(paraboloid_x, paraboloid_copy))
- self.wait()
-
-
- 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)
- unit_vector = reference_line.get_unit_vector() * scale
- vector = Line(coord_i - unit_vector, coord_i + unit_vector, color = BLUE_E, buff=0)
- return vector
-
-
-class PartialDerivY(ThreeDScene):
- def construct(self):
- axes = ThreeDAxes()
-
- paraboloid = ParametricSurface(
- lambda u, v: np.array([
- 2*np.sin(u)*np.cos(v),
- 2*np.sin(u)*np.sin(v),
- -2*2*np.sin(u)*np.sin(u)+2
- ]),u_min=0,u_max=PI/2,v_min=0,v_max=2*PI,checkerboard_colors=[PINK, PURPLE],
- resolution=(15, 32)).scale(1)
-
- paraboloid_copy = paraboloid.copy()
-
-
- paraboloid_y = ParametricSurface(
- lambda u, v: np.array([
- 2*np.sin(u)*np.cos(v),
- 2*np.sin(u)*np.sin(v),
- -2*2*np.sin(u)*np.sin(u)+2
- ]),u_min=0,u_max=PI/2,v_min=PI/2,v_max=3*PI/2,checkerboard_colors=[PINK, PURPLE],
- resolution=(15, 32)).scale(1)
-
-
- parabola =ParametricFunction(
- lambda u : np.array([
- 0,
- u,
- -(u*u) + 2
- ]),color=YELLOW_C,t_min=-2,t_max=2,
- )
-
- plane = Polygon(np.array([0,-2.2,-2.5]),np.array([0,2.2,-2.5]),np.array([0,2.2,2.5]),np.array([0,-2.2,2.5]),np.array([0,-2.2,-2.5]), color = BLUE, fill_color = BLUE, fill_opacity = 0.2)
- plane_text = TextMobject(r"$x = 0$", color = BLUE_C).move_to(2*UP + 3*RIGHT)
-
- surface_eqn = TextMobject("Surface", r"$z = 2- x^2 -y^2$", color = PINK).scale(0.6).move_to(np.array([3*LEFT +3*UP]))
- surface_eqn[0].set_color(BLUE_C)
-
- line = Line(np.array([0,-2,0]), np.array([0,2,0]), color = RED_C)
-
- self.add(axes)
-
- axis = TextMobject(r"X",r"Y",r"Z")
- axis[0].move_to(6*RIGHT)
- axis[1].move_to(6*UP)
- axis[2].move_to(3.7*UP)
-
- self.add_fixed_in_frame_mobjects(axis[2])
- self.add_fixed_orientation_mobjects(axis[0])
- self.add_fixed_orientation_mobjects(axis[1])
-
- self.set_camera_orientation(phi=80 * DEGREES, theta = 45*DEGREES)
-
- self.play(Write(paraboloid))
-
- self.add_fixed_in_frame_mobjects(surface_eqn)
- #self.move_camera(phi=80* DEGREES,theta=5*DEGREES)
- self.play(ShowCreation(plane))
- self.add_fixed_in_frame_mobjects(plane_text)
- self.wait()
- self.play(ReplacementTransform(paraboloid, paraboloid_y))
- self.play(FadeOut(plane), FadeOut(plane_text))
- self.play(ShowCreation(parabola), ShowCreation(line))
-
- text1 = TextMobject("Moving small", r"$dy$", r"steps").scale(0.6).move_to(3*UP + 3.5*RIGHT).set_color_by_gradient(RED, ORANGE, YELLOW, BLUE, PURPLE)
-
- text2 = TextMobject("Observing change in function, keeping", r"$x$", r"constant").scale(0.6).move_to(2.6*UP + 3.5*RIGHT).set_color_by_gradient(RED, ORANGE, YELLOW, GREEN, BLUE, PURPLE)
-
- slope_text = TexMobject("Slope =", "{\\partial", "f", "\\over", "\\partial", "y}").scale(0.6).move_to(2*UP + 3.5*RIGHT)
- slope_text[0].set_color("#006400")
- slope_text.set_color_by_tex("\\partial",PINK)
- slope_text.set_color_by_tex("f",YELLOW_C)
- slope_text[5].set_color(RED_C)
-
- self.add_fixed_in_frame_mobjects(text1, text2)
- self.wait()
- self.add_fixed_in_frame_mobjects(slope_text)
-
- dot = Dot().rotate(PI/2).set_color(RED_C)
- alpha = ValueTracker(0)
- vector = self.get_tangent_vector(alpha.get_value(),parabola,scale=1.5)
- dot.add_updater(lambda m: m.move_to(vector.get_center()))
- self.play(
- ShowCreation(parabola),
- GrowFromCenter(dot),
- GrowArrow(vector)
- )
- vector.add_updater(
- lambda m: m.become(
- self.get_tangent_vector(alpha.get_value()%1,parabola,scale=1.5)
- )
- )
- self.add(vector,dot)
- self.play(alpha.increment_value, 1, run_time=10, rate_func=linear)
- self.wait()
-
- '''
- for i in np.arange(-2,2,0.2):
- self.play(ReplacementTransform(Line(np.array([0,i,0]), np.array([0,i,-i*i + 2]), color = BLUE_C), Line(np.array([0,i+0.2,0]), np.array([0,i+0.2,-(i+0.2)**2 + 2]), color = BLUE_C)))
- #self.wait()
- '''
-
-
- self.wait()
- self.play(FadeOut(parabola), FadeOut(line), FadeOut(vector), FadeOut(dot), FadeOut(text1), FadeOut(text2), FadeOut(slope_text),FadeOut(surface_eqn))
-
- #self.move_camera(phi=80* DEGREES,theta= 90*DEGREES)
- self.play(ReplacementTransform(paraboloid_y, paraboloid_copy))
- self.wait()
-
- 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)
- unit_vector = reference_line.get_unit_vector() * scale
- vector = Line(coord_i - unit_vector, coord_i + unit_vector, color = "#006400", buff=0)
- return vector
-
-
\ No newline at end of file
--
cgit
From 5ee6f0880a95632e35fc7b7d001d2f2aa6d2bc0c Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Sat, 4 Jul 2020 12:39:49 +0530
Subject: Add files via upload
---
.../file4_partial_deriv_example.py | 246 +++++++++++++++++++++
1 file changed, 246 insertions(+)
create mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/file4_partial_deriv_example.py
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/file4_partial_deriv_example.py b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/file4_partial_deriv_example.py
new file mode 100644
index 0000000..0a5832d
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/file4_partial_deriv_example.py
@@ -0,0 +1,246 @@
+from manimlib.imports import *
+
+class PartialDerivX(ThreeDScene):
+ def construct(self):
+ axes = ThreeDAxes()
+
+ paraboloid = ParametricSurface(
+ lambda u, v: np.array([
+ 2*np.sin(u)*np.cos(v),
+ 2*np.sin(u)*np.sin(v),
+ -2*2*np.sin(u)*np.sin(u)+2
+ ]),u_min=0,u_max=PI/2,v_min=0,v_max=2*PI,checkerboard_colors=[PINK, PURPLE],
+ resolution=(15, 32)).scale(1)
+
+ paraboloid_copy = paraboloid.copy()
+
+
+ paraboloid_x = ParametricSurface(
+ lambda u, v: np.array([
+ 2*np.sin(u)*np.cos(v),
+ 2*np.sin(u)*np.sin(v),
+ -2*2*np.sin(u)*np.sin(u)+2
+ ]),u_min=0,u_max=PI/2,v_min=PI,v_max=2*PI,checkerboard_colors=[PINK, PURPLE],
+ resolution=(15, 32)).scale(1)
+
+
+ parabola =ParametricFunction(
+ lambda u : np.array([
+ u,
+ 0,
+ -(u*u) + 2
+ ]),color="#006400",t_min=-2,t_max=2,
+ )
+
+ plane = Polygon(np.array([-2.2,0,-2.5]),np.array([2.2,0,-2.5]),np.array([2.2,0,2.5]),np.array([-2.2,0,2.5]),np.array([-2.2,0,-2.5]), color = GREEN, fill_color = GREEN, fill_opacity = 0.2)
+ plane_text = TextMobject(r"$y = 0$", color = GREEN_C).move_to(2*UP + 3*RIGHT)
+
+ surface_eqn = TextMobject("Surface", r"$z = f(x,y) = 2 - x^2 - y^2$", color = BLUE_C).scale(0.6).move_to(np.array([3*LEFT +3*UP]))
+ surface_eqn[0].set_color(PINK)
+
+ line = Line(np.array([-2,0,0]), np.array([2,0,0]), color = RED_C)
+
+
+ self.add(axes)
+
+ axis = TextMobject(r"X",r"Y",r"Z")
+ axis[0].move_to(6*RIGHT)
+ axis[1].move_to(6*UP)
+ axis[2].move_to(3.7*UP)
+
+ self.add_fixed_in_frame_mobjects(axis[2])
+ self.add_fixed_orientation_mobjects(axis[0])
+ self.add_fixed_orientation_mobjects(axis[1])
+
+
+ self.set_camera_orientation(phi=80 * DEGREES, theta = 0*DEGREES)
+
+ self.play(Write(paraboloid))
+
+ self.add_fixed_in_frame_mobjects(surface_eqn)
+ #self.move_camera(phi=80* DEGREES,theta=95*DEGREES)
+ self.move_camera(phi=80* DEGREES,theta=45*DEGREES)
+ self.play(ShowCreation(plane))
+ self.add_fixed_in_frame_mobjects(plane_text)
+ self.wait()
+ self.play(ReplacementTransform(paraboloid, paraboloid_x))
+ self.play(FadeOut(plane), FadeOut(plane_text))
+ self.play(ShowCreation(parabola), ShowCreation(line))
+
+ text1 = TextMobject("Moving small", r"$dx$", r"steps").scale(0.6).move_to(3*UP + 3.5*RIGHT).set_color_by_gradient(RED, ORANGE, YELLOW, BLUE, PURPLE)
+
+ text2 = TextMobject("Observing change in function, keeping", r"$y$", r"constant").scale(0.6).move_to(2.6*UP + 3.5*RIGHT).set_color_by_gradient(RED, ORANGE, YELLOW, GREEN, BLUE, PURPLE)
+
+ slope_text = TexMobject("Slope =", "{\\partial", "f", "\\over", "\\partial", "x}").scale(0.6).move_to(2*UP + 3.5*RIGHT)
+ slope_text[0].set_color(BLUE_E)
+ slope_text.set_color_by_tex("\\partial",PINK)
+ slope_text.set_color_by_tex("f","#006400")
+ slope_text[5].set_color(RED_C)
+
+ self.add_fixed_in_frame_mobjects(text1, text2)
+ self.wait()
+ self.add_fixed_in_frame_mobjects(slope_text)
+ #add_fixed_orientation_mobjects
+
+
+ dot = Dot().rotate(PI/2).set_color(RED_C)
+ alpha = ValueTracker(0)
+ vector = self.get_tangent_vector(alpha.get_value(),parabola,scale=1.5)
+ dot.add_updater(lambda m: m.move_to(vector.get_center()))
+ self.play(
+ ShowCreation(parabola),
+ GrowFromCenter(dot),
+ GrowArrow(vector)
+ )
+ vector.add_updater(
+ lambda m: m.become(
+ self.get_tangent_vector(alpha.get_value()%1,parabola,scale=1.5)
+ )
+ )
+ self.add(vector,dot)
+ self.play(alpha.increment_value, 1, run_time=10, rate_func=linear)
+ self.wait()
+
+
+ '''
+ for i in np.arange(-2,2,0.2):
+ self.play(ReplacementTransform(Line(np.array([i,0,0]), np.array([i,0,-i*i + 2]), color = GREEN_C), Line(np.array([i+0.2,0,0]), np.array([i+0.2,0,-(i+0.2)**2 + 2]), color = GREEN_C)))
+ #self.wait()
+ '''
+
+ self.wait()
+ self.play(FadeOut(parabola), FadeOut(line), FadeOut(vector), FadeOut(dot), FadeOut(text1), FadeOut(text2), FadeOut(slope_text),FadeOut(surface_eqn))
+
+ #self.move_camera(phi=80* DEGREES,theta= 0*DEGREES)
+ self.play(ReplacementTransform(paraboloid_x, paraboloid_copy))
+ self.wait()
+
+
+ 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)
+ unit_vector = reference_line.get_unit_vector() * scale
+ vector = Line(coord_i - unit_vector, coord_i + unit_vector, color = BLUE_E, buff=0)
+ return vector
+
+
+class PartialDerivY(ThreeDScene):
+ def construct(self):
+ axes = ThreeDAxes()
+
+ paraboloid = ParametricSurface(
+ lambda u, v: np.array([
+ 2*np.sin(u)*np.cos(v),
+ 2*np.sin(u)*np.sin(v),
+ -2*2*np.sin(u)*np.sin(u)+2
+ ]),u_min=0,u_max=PI/2,v_min=0,v_max=2*PI,checkerboard_colors=[PINK, PURPLE],
+ resolution=(15, 32)).scale(1)
+
+ paraboloid_copy = paraboloid.copy()
+
+
+ paraboloid_y = ParametricSurface(
+ lambda u, v: np.array([
+ 2*np.sin(u)*np.cos(v),
+ 2*np.sin(u)*np.sin(v),
+ -2*2*np.sin(u)*np.sin(u)+2
+ ]),u_min=0,u_max=PI/2,v_min=PI/2,v_max=3*PI/2,checkerboard_colors=[PINK, PURPLE],
+ resolution=(15, 32)).scale(1)
+
+
+ parabola =ParametricFunction(
+ lambda u : np.array([
+ 0,
+ u,
+ -(u*u) + 2
+ ]),color=YELLOW_C,t_min=-2,t_max=2,
+ )
+
+ plane = Polygon(np.array([0,-2.2,-2.5]),np.array([0,2.2,-2.5]),np.array([0,2.2,2.5]),np.array([0,-2.2,2.5]),np.array([0,-2.2,-2.5]), color = BLUE, fill_color = BLUE, fill_opacity = 0.2)
+ plane_text = TextMobject(r"$x = 0$", color = BLUE_C).move_to(2*UP + 3*RIGHT)
+
+ surface_eqn = TextMobject("Surface", r"$z = f(x,y) = 2 - x^2 - y^2$", color = BLUE_C ).scale(0.6).move_to(np.array([3*LEFT +3*UP]))
+ surface_eqn[0].set_color(PINK)
+
+ line = Line(np.array([0,-2,0]), np.array([0,2,0]), color = RED_C)
+
+ self.add(axes)
+
+ axis = TextMobject(r"X",r"Y",r"Z")
+ axis[0].move_to(6*RIGHT)
+ axis[1].move_to(6*UP)
+ axis[2].move_to(3.7*UP)
+
+ self.add_fixed_in_frame_mobjects(axis[2])
+ self.add_fixed_orientation_mobjects(axis[0])
+ self.add_fixed_orientation_mobjects(axis[1])
+
+ self.set_camera_orientation(phi=80 * DEGREES, theta = 45*DEGREES)
+
+ self.play(Write(paraboloid))
+
+ self.add_fixed_in_frame_mobjects(surface_eqn)
+ #self.move_camera(phi=80* DEGREES,theta=5*DEGREES)
+ self.play(ShowCreation(plane))
+ self.add_fixed_in_frame_mobjects(plane_text)
+ self.wait()
+ self.play(ReplacementTransform(paraboloid, paraboloid_y))
+ self.play(FadeOut(plane), FadeOut(plane_text))
+ self.play(ShowCreation(parabola), ShowCreation(line))
+
+ text1 = TextMobject("Moving small", r"$dy$", r"steps").scale(0.6).move_to(3*UP + 3.5*RIGHT).set_color_by_gradient(RED, ORANGE, YELLOW, BLUE, PURPLE)
+
+ text2 = TextMobject("Observing change in function, keeping", r"$x$", r"constant").scale(0.6).move_to(2.6*UP + 3.5*RIGHT).set_color_by_gradient(RED, ORANGE, YELLOW, GREEN, BLUE, PURPLE)
+
+ slope_text = TexMobject("Slope =", "{\\partial", "f", "\\over", "\\partial", "y}").scale(0.6).move_to(2*UP + 3.5*RIGHT)
+ slope_text[0].set_color("#006400")
+ slope_text.set_color_by_tex("\\partial",PINK)
+ slope_text.set_color_by_tex("f",YELLOW_C)
+ slope_text[5].set_color(RED_C)
+
+ self.add_fixed_in_frame_mobjects(text1, text2)
+ self.wait()
+ self.add_fixed_in_frame_mobjects(slope_text)
+
+ dot = Dot().rotate(PI/2).set_color(RED_C)
+ alpha = ValueTracker(0)
+ vector = self.get_tangent_vector(alpha.get_value(),parabola,scale=1.5)
+ dot.add_updater(lambda m: m.move_to(vector.get_center()))
+ self.play(
+ ShowCreation(parabola),
+ GrowFromCenter(dot),
+ GrowArrow(vector)
+ )
+ vector.add_updater(
+ lambda m: m.become(
+ self.get_tangent_vector(alpha.get_value()%1,parabola,scale=1.5)
+ )
+ )
+ self.add(vector,dot)
+ self.play(alpha.increment_value, 1, run_time=10, rate_func=linear)
+ self.wait()
+
+ '''
+ for i in np.arange(-2,2,0.2):
+ self.play(ReplacementTransform(Line(np.array([0,i,0]), np.array([0,i,-i*i + 2]), color = BLUE_C), Line(np.array([0,i+0.2,0]), np.array([0,i+0.2,-(i+0.2)**2 + 2]), color = BLUE_C)))
+ #self.wait()
+ '''
+
+
+ self.wait()
+ self.play(FadeOut(parabola), FadeOut(line), FadeOut(vector), FadeOut(dot), FadeOut(text1), FadeOut(text2), FadeOut(slope_text),FadeOut(surface_eqn))
+
+ #self.move_camera(phi=80* DEGREES,theta= 90*DEGREES)
+ self.play(ReplacementTransform(paraboloid_y, paraboloid_copy))
+ self.wait()
+
+ 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)
+ unit_vector = reference_line.get_unit_vector() * scale
+ vector = Line(coord_i - unit_vector, coord_i + unit_vector, color = "#006400", buff=0)
+ return vector
+
+
\ No newline at end of file
--
cgit
From b76b674fd058ccf1e9201458136c01a0361b1709 Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Sat, 4 Jul 2020 12:40:27 +0530
Subject: Delete file4_partial_deriv_example.gif
---
.../gifs/file4_partial_deriv_example.gif | Bin 4953394 -> 0 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file4_partial_deriv_example.gif
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file4_partial_deriv_example.gif b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file4_partial_deriv_example.gif
deleted file mode 100644
index d2bf541..0000000
Binary files a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file4_partial_deriv_example.gif and /dev/null differ
--
cgit
From 81747de0e0457880d47e4c89a618bdf15724e5eb Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Sat, 4 Jul 2020 12:41:38 +0530
Subject: Add files via upload
---
.../gifs/file4_partial_deriv_example.gif | Bin 0 -> 4952337 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file4_partial_deriv_example.gif
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file4_partial_deriv_example.gif b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file4_partial_deriv_example.gif
new file mode 100644
index 0000000..32cce4c
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file4_partial_deriv_example.gif differ
--
cgit
From e31e7b7c66aef17ffa32862c6196fd622828a8fa Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Sat, 4 Jul 2020 12:47:02 +0530
Subject: Delete file3_partial_deriv_defn.gif
---
.../gifs/file3_partial_deriv_defn.gif | Bin 5251558 -> 0 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file3_partial_deriv_defn.gif
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file3_partial_deriv_defn.gif b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file3_partial_deriv_defn.gif
deleted file mode 100644
index c66b3fa..0000000
Binary files a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file3_partial_deriv_defn.gif and /dev/null differ
--
cgit
From 32cb738575bc291165e75b150bc0122720ea0579 Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Sat, 4 Jul 2020 12:48:33 +0530
Subject: Add files via upload
---
.../gifs/file3_partial_deriv_defn.gif | Bin 0 -> 5249722 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file3_partial_deriv_defn.gif
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file3_partial_deriv_defn.gif b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file3_partial_deriv_defn.gif
new file mode 100644
index 0000000..4dd1eee
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file3_partial_deriv_defn.gif differ
--
cgit
From 1ba33c8f4119867130ff6d95c4f7fe8a5df3f752 Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Sat, 4 Jul 2020 12:49:48 +0530
Subject: Delete file3_partial_deriv_defn.py
---
.../file3_partial_deriv_defn.py | 218 ---------------------
1 file changed, 218 deletions(-)
delete mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/file3_partial_deriv_defn.py
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/file3_partial_deriv_defn.py b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/file3_partial_deriv_defn.py
deleted file mode 100644
index a25ca56..0000000
--- a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/file3_partial_deriv_defn.py
+++ /dev/null
@@ -1,218 +0,0 @@
-from manimlib.imports import *
-
-class PartialDeriv(ThreeDScene):
- def construct(self):
- axes = ThreeDAxes()
-
- paraboloid = ParametricSurface(
- lambda u, v: np.array([
- 2*np.sin(u)*np.cos(v),
- 2*np.sin(u)*np.sin(v),
- -2*2*np.sin(u)*np.sin(u)+2
- ]),u_min=0,u_max=PI/2,v_min=0,v_max=2*PI,checkerboard_colors=[PINK, PURPLE],
- resolution=(15, 32)).scale(1)
-
- paraboloid_copy1 = paraboloid.copy()
- paraboloid_copy2 = paraboloid.copy()
-
- paraboloid_x = ParametricSurface(
- lambda u, v: np.array([
- 2*np.sin(u)*np.cos(v),
- 2*np.sin(u)*np.sin(v),
- -2*2*np.sin(u)*np.sin(u)+2
- ]),u_min=0,u_max=PI/2,v_min=PI,v_max=2*PI,checkerboard_colors=[PINK, PURPLE],
- resolution=(15, 32)).scale(1)
-
- paraboloid_x_copy = paraboloid_x.copy()
-
- paraboloid_y = ParametricSurface(
- lambda u, v: np.array([
- 2*np.sin(u)*np.cos(v),
- 2*np.sin(u)*np.sin(v),
- -2*2*np.sin(u)*np.sin(u)+2
- ]),u_min=0,u_max=PI/2,v_min=PI/2,v_max=3*PI/2,checkerboard_colors=[PINK, PURPLE],
- resolution=(15, 32)).scale(1)
-
- parabola1 =ParametricFunction(
- lambda u : np.array([
- u,
- 0,
- -(u*u) + 2
- ]),color="#006400",t_min=-2,t_max=2,
- )
- parabola2 =ParametricFunction(
- lambda u : np.array([
- 0,
- u,
- -(u*u) + 2
- ]),color=BLUE_C,t_min=-2,t_max=2,
- )
-
- plane1 = Polygon(np.array([-2.2,0,-2.5]),np.array([2.2,0,-2.5]),np.array([2.2,0,2.5]),np.array([-2.2,0,2.5]),np.array([-2.2,0,-2.5]), color = GREEN, fill_color = GREEN, fill_opacity = 0.2)
- plane1_text = TextMobject(r"$y = 0$", color = GREEN_C).move_to(2*UP + 3.3*RIGHT)
-
- plane2 = Polygon(np.array([0,-2.2,-2.5]),np.array([0,2.2,-2.5]),np.array([0,2.2,2.5]),np.array([0,-2.2,2.5]),np.array([0,-2.2,-2.5]), color = BLUE, fill_color = BLUE, fill_opacity = 0.2)
- plane2_text = TextMobject(r"$x = 0$", color = BLUE_C).move_to(2*UP + 3.2*RIGHT)
-
- surface_eqn = TextMobject("Surface", r"$z = 2- x^2 -y^2$", color = YELLOW_C).scale(0.6).move_to(np.array([3*LEFT +3*UP]))
- surface_eqn[0].set_color(PINK)
-
- dot1 =Sphere(radius=0.08).move_to(np.array([-1,0,1]))
- dot1.set_fill(RED)
- line1 = Line(np.array([-1.55, 0,0]), np.array([-0.4, 0,2.2]), color = RED)
- lab_x = TextMobject(r"$f(x_0,y_0)$", color = RED).scale(0.7)
- para_lab_x = TextMobject(r"$f(x,y_0)$", color = "#006400").scale(0.7)
- tangent_line_x = TextMobject("Tangent Line", color = RED_C, buff = 0.4).scale(0.6).move_to(np.array([1.7*RIGHT +1.8*UP]))
-
-
- text1 = TextMobject(r"$\frac{\partial f}{\partial x}\vert_{(x_0,y_0)} = \frac{d}{dx}$", r"$f(x,y_0)$", r"$\vert_{x=x_0}$").scale(0.6)
- brace1 = Brace(text1[1], DOWN, buff = SMALL_BUFF, color = GREEN)
- t1 = brace1.get_text("Just depends on x")
- t1.scale(0.6)
- t1.set_color(GREEN)
-
-
- dot2 =Sphere(radius=0.08).move_to(np.array([0,1,1]))
- dot2.set_fill(RED)
- line2 = Line(np.array([0, 1.55,0]), np.array([0, 0.4,2.2]), color = RED)
- lab_y = TextMobject(r"$f(x_0,y_0)$", color = RED).scale(0.7)
- para_lab_y = TextMobject(r"$f(x_0,y)$", color = BLUE_C).scale(0.7)
- tangent_line_y = TextMobject("Tangent Line", color = RED_C, buff = 0.4).scale(0.6).move_to(np.array([1.7*RIGHT +1.8*UP]))
-
- text2 = TextMobject(r"$\frac{\partial f}{\partial y}\vert_{(x_0,y_0)} = \frac{d}{dy}$", r"$f(x_0,y)$", r"$\vert_{y=y_0}$").scale(0.6)
- brace2 = Brace(text2[1], DOWN, buff = SMALL_BUFF, color = GREEN)
- t2 = brace2.get_text("Just depends on y")
- t2.scale(0.6)
- t2.set_color(GREEN)
-
- text3 = TextMobject(r"$= \lim_{h \to 0} \frac{f(x_0+h,y_0) - f(x_0,y_0)}{h}$").scale(0.6)
-
- dot3 =Sphere(radius=0.08).move_to(np.array([-1.22,0,0.5]))
- dot3.set_fill(YELLOW_C)
- line3 = Line(np.array([-1.44,0,0]), np.array([-0.6,0,2.2]), color = YELLOW_C)
- lab_line3 = TextMobject(r"$f(x_0+h,y_0)$", color = YELLOW_C).scale(0.7)
-
-
- self.set_camera_orientation(phi=80 * DEGREES, theta = 0*DEGREES)
- #self.set_camera_orientation(phi=80 * DEGREES, theta = 20*DEGREES)
- #self.begin_ambient_camera_rotation(rate=0.3)
-
-
- self.add(axes)
-
- axis = TextMobject(r"X",r"Y",r"Z")
- axis[0].move_to(6*RIGHT)
- axis[1].move_to(6*UP)
- axis[2].move_to(3.7*UP)
-
- self.add_fixed_in_frame_mobjects(axis[2])
- #self.add_fixed_orientation_mobjects(axis[2])
-
- self.play(Write(paraboloid))
-
- self.add_fixed_in_frame_mobjects(surface_eqn)
- #self.move_camera(phi=80* DEGREES,theta=110*DEGREES)
- self.move_camera(phi=80* DEGREES,theta=45*DEGREES)
-
- self.add_fixed_orientation_mobjects(axis[0])
- self.add_fixed_orientation_mobjects(axis[1])
- self.play(ShowCreation(plane1))
- self.add_fixed_in_frame_mobjects(plane1_text)
- self.wait()
- self.play(ReplacementTransform(paraboloid, paraboloid_x))
-
- lab_x.move_to(np.array([1.8*RIGHT +1.15*UP]))
- para_lab_x.move_to(np.array([1.3*LEFT +1.6*UP]))
- self.wait()
- self.play(FadeOut(plane1), FadeOut(plane1_text))
- self.play(ShowCreation(parabola1))
- self.add_fixed_in_frame_mobjects(para_lab_x)
- self.play(ShowCreation(dot1))
- self.add_fixed_in_frame_mobjects(lab_x)
- #self.play(ShowCreation(dot1))
- self.wait()
- self.play(ShowCreation(line1))
- self.add_fixed_in_frame_mobjects(tangent_line_x)
- self.wait()
-
- self.add_fixed_in_frame_mobjects(text1, brace1, t1)
- grp1 = VGroup(text1, brace1, t1)
- grp1.move_to(3*UP+3*RIGHT)
- self.play(Write(text1),GrowFromCenter(brace1), FadeIn(t1))
- self.wait()
- self.play(FadeOut(parabola1), FadeOut(line1), FadeOut(lab_x), FadeOut(para_lab_x), FadeOut(dot1), FadeOut(tangent_line_x),FadeOut(grp1))
-
-
-
-
- #self.move_camera(phi=80* DEGREES,theta=20*DEGREES)
-
- self.play(ReplacementTransform(paraboloid_x, paraboloid_copy1))
- self.wait()
- self.play(ShowCreation(plane2))
- self.add_fixed_in_frame_mobjects(plane2_text)
- self.wait()
- self.play(ReplacementTransform(paraboloid_copy1, paraboloid_y))
-
- lab_y.move_to(np.array([1.8*RIGHT +1.15*UP]))
- para_lab_y.move_to(np.array([1.3*LEFT +1.6*UP]))
- self.wait()
- self.play(FadeOut(plane2), FadeOut(plane2_text))
- self.play(ShowCreation(parabola2))
- self.add_fixed_in_frame_mobjects(para_lab_y)
- self.play(ShowCreation(dot2))
- self.add_fixed_in_frame_mobjects(lab_y)
- self.wait()
- self.play(ShowCreation(line2))
- self.add_fixed_in_frame_mobjects(tangent_line_y)
- self.wait()
-
- self.add_fixed_in_frame_mobjects(text2, brace2, t2)
- grp2 = VGroup(text2, brace2, t2)
- grp2.move_to(3*UP+3*RIGHT)
- self.play(Write(text2),GrowFromCenter(brace2), FadeIn(t2))
- self.wait()
- self.play(FadeOut(parabola2), FadeOut(line2), FadeOut(lab_y), FadeOut(para_lab_y), FadeOut(dot2), FadeOut(tangent_line_y), FadeOut(grp2))
- self.wait()
-
-
- #self.move_camera(phi=80* DEGREES,theta=105*DEGREES)
- self.play(ReplacementTransform(paraboloid_y, paraboloid_copy2))
- self.wait()
-
-
- self.play(ShowCreation(plane1))
- self.add_fixed_in_frame_mobjects(plane1_text)
- self.wait()
- self.play(ReplacementTransform(paraboloid_copy2, paraboloid_x_copy))
-
- lab_x.move_to(np.array([1.8*RIGHT +1.15*UP]))
- para_lab_x.move_to(np.array([1.3*LEFT +1.6*UP]))
- lab_line3.move_to(np.array([2.4*RIGHT +0.5*UP]))
- self.wait()
- self.play(FadeOut(plane1), FadeOut(plane1_text))
- self.play(ShowCreation(parabola1))
- self.add_fixed_in_frame_mobjects(para_lab_x)
- self.play(ShowCreation(dot1))
- self.add_fixed_in_frame_mobjects(lab_x)
- self.play(ShowCreation(dot3))
- self.add_fixed_in_frame_mobjects(lab_line3)
- self.wait()
- self.play(ShowCreation(line1))
- self.add_fixed_in_frame_mobjects(tangent_line_x)
- self.play(ShowCreation(line3))
- self.wait()
-
-
- self.add_fixed_in_frame_mobjects(text1,text3)
- text1.move_to(3*UP+3*RIGHT)
- text3.next_to(text1, DOWN)
- self.play(Write(text1),Write(text3))
- self.wait()
- self.play(FadeOut(parabola1), FadeOut(line1), FadeOut(lab_x), FadeOut(line3), FadeOut(lab_line3), FadeOut(para_lab_x), FadeOut(dot1), FadeOut(dot3), FadeOut(tangent_line_x), FadeOut(text1), FadeOut(text3))
- self.wait()
-
-
-
-
-
--
cgit
From db429773e06bcdeb316a90f4786924de7355a263 Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Sat, 4 Jul 2020 12:50:27 +0530
Subject: Add files via upload
---
.../file3_partial_deriv_defn.py | 218 +++++++++++++++++++++
1 file changed, 218 insertions(+)
create mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/file3_partial_deriv_defn.py
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/file3_partial_deriv_defn.py b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/file3_partial_deriv_defn.py
new file mode 100644
index 0000000..2b60e16
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/file3_partial_deriv_defn.py
@@ -0,0 +1,218 @@
+from manimlib.imports import *
+
+class PartialDeriv(ThreeDScene):
+ def construct(self):
+ axes = ThreeDAxes()
+
+ paraboloid = ParametricSurface(
+ lambda u, v: np.array([
+ 2*np.sin(u)*np.cos(v),
+ 2*np.sin(u)*np.sin(v),
+ -2*2*np.sin(u)*np.sin(u)+2
+ ]),u_min=0,u_max=PI/2,v_min=0,v_max=2*PI,checkerboard_colors=[PINK, PURPLE],
+ resolution=(15, 32)).scale(1)
+
+ paraboloid_copy1 = paraboloid.copy()
+ paraboloid_copy2 = paraboloid.copy()
+
+ paraboloid_x = ParametricSurface(
+ lambda u, v: np.array([
+ 2*np.sin(u)*np.cos(v),
+ 2*np.sin(u)*np.sin(v),
+ -2*2*np.sin(u)*np.sin(u)+2
+ ]),u_min=0,u_max=PI/2,v_min=PI,v_max=2*PI,checkerboard_colors=[PINK, PURPLE],
+ resolution=(15, 32)).scale(1)
+
+ paraboloid_x_copy = paraboloid_x.copy()
+
+ paraboloid_y = ParametricSurface(
+ lambda u, v: np.array([
+ 2*np.sin(u)*np.cos(v),
+ 2*np.sin(u)*np.sin(v),
+ -2*2*np.sin(u)*np.sin(u)+2
+ ]),u_min=0,u_max=PI/2,v_min=PI/2,v_max=3*PI/2,checkerboard_colors=[PINK, PURPLE],
+ resolution=(15, 32)).scale(1)
+
+ parabola1 =ParametricFunction(
+ lambda u : np.array([
+ u,
+ 0,
+ -(u*u) + 2
+ ]),color="#006400",t_min=-2,t_max=2,
+ )
+ parabola2 =ParametricFunction(
+ lambda u : np.array([
+ 0,
+ u,
+ -(u*u) + 2
+ ]),color=BLUE_C,t_min=-2,t_max=2,
+ )
+
+ plane1 = Polygon(np.array([-2.2,0,-2.5]),np.array([2.2,0,-2.5]),np.array([2.2,0,2.5]),np.array([-2.2,0,2.5]),np.array([-2.2,0,-2.5]), color = GREEN, fill_color = GREEN, fill_opacity = 0.2)
+ plane1_text = TextMobject(r"$y = 0$", color = GREEN_C).move_to(2*UP + 3.3*RIGHT)
+
+ plane2 = Polygon(np.array([0,-2.2,-2.5]),np.array([0,2.2,-2.5]),np.array([0,2.2,2.5]),np.array([0,-2.2,2.5]),np.array([0,-2.2,-2.5]), color = BLUE, fill_color = BLUE, fill_opacity = 0.2)
+ plane2_text = TextMobject(r"$x = 0$", color = BLUE_C).move_to(2*UP + 3.2*RIGHT)
+
+ surface_eqn = TextMobject("Surface", r"$z = f(x,y) = 2 - x^2 - y^2$", color = YELLOW_C).scale(0.6).move_to(np.array([3*LEFT +3*UP]))
+ surface_eqn[0].set_color(PINK)
+
+ dot1 =Sphere(radius=0.08).move_to(np.array([-1,0,1]))
+ dot1.set_fill(RED)
+ line1 = Line(np.array([-1.55, 0,0]), np.array([-0.4, 0,2.2]), color = RED)
+ lab_x = TextMobject(r"$f(x_0,y_0)$", color = RED).scale(0.7)
+ para_lab_x = TextMobject(r"$f(x,y_0)$", color = "#006400").scale(0.7)
+ tangent_line_x = TextMobject("Tangent Line", color = RED_C, buff = 0.4).scale(0.6).move_to(np.array([1.7*RIGHT +1.8*UP]))
+
+
+ text1 = TextMobject(r"$\frac{\partial f}{\partial x}\vert_{(x_0,y_0)} = \frac{d}{dx}$", r"$f(x,y_0)$", r"$\vert_{x=x_0}$").scale(0.6)
+ brace1 = Brace(text1[1], DOWN, buff = SMALL_BUFF, color = GREEN)
+ t1 = brace1.get_text("Just depends on x")
+ t1.scale(0.6)
+ t1.set_color(GREEN)
+
+
+ dot2 =Sphere(radius=0.08).move_to(np.array([0,1,1]))
+ dot2.set_fill(RED)
+ line2 = Line(np.array([0, 1.55,0]), np.array([0, 0.4,2.2]), color = RED)
+ lab_y = TextMobject(r"$f(x_0,y_0)$", color = RED).scale(0.7)
+ para_lab_y = TextMobject(r"$f(x_0,y)$", color = BLUE_C).scale(0.7)
+ tangent_line_y = TextMobject("Tangent Line", color = RED_C, buff = 0.4).scale(0.6).move_to(np.array([1.7*RIGHT +1.8*UP]))
+
+ text2 = TextMobject(r"$\frac{\partial f}{\partial y}\vert_{(x_0,y_0)} = \frac{d}{dy}$", r"$f(x_0,y)$", r"$\vert_{y=y_0}$").scale(0.6)
+ brace2 = Brace(text2[1], DOWN, buff = SMALL_BUFF, color = GREEN)
+ t2 = brace2.get_text("Just depends on y")
+ t2.scale(0.6)
+ t2.set_color(GREEN)
+
+ text3 = TextMobject(r"$= \lim_{h \to 0} \frac{f(x_0+h,y_0) - f(x_0,y_0)}{h}$").scale(0.6)
+
+ dot3 =Sphere(radius=0.08).move_to(np.array([-1.22,0,0.5]))
+ dot3.set_fill(YELLOW_C)
+ line3 = Line(np.array([-1.44,0,0]), np.array([-0.6,0,2.2]), color = YELLOW_C)
+ lab_line3 = TextMobject(r"$f(x_0+h,y_0)$", color = YELLOW_C).scale(0.7)
+
+
+ self.set_camera_orientation(phi=80 * DEGREES, theta = 0*DEGREES)
+ #self.set_camera_orientation(phi=80 * DEGREES, theta = 20*DEGREES)
+ #self.begin_ambient_camera_rotation(rate=0.3)
+
+
+ self.add(axes)
+
+ axis = TextMobject(r"X",r"Y",r"Z")
+ axis[0].move_to(6*RIGHT)
+ axis[1].move_to(6*UP)
+ axis[2].move_to(3.7*UP)
+
+ self.add_fixed_in_frame_mobjects(axis[2])
+ #self.add_fixed_orientation_mobjects(axis[2])
+
+ self.play(Write(paraboloid))
+
+ self.add_fixed_in_frame_mobjects(surface_eqn)
+ #self.move_camera(phi=80* DEGREES,theta=110*DEGREES)
+ self.move_camera(phi=80* DEGREES,theta=45*DEGREES)
+
+ self.add_fixed_orientation_mobjects(axis[0])
+ self.add_fixed_orientation_mobjects(axis[1])
+ self.play(ShowCreation(plane1))
+ self.add_fixed_in_frame_mobjects(plane1_text)
+ self.wait()
+ self.play(ReplacementTransform(paraboloid, paraboloid_x))
+
+ lab_x.move_to(np.array([1.8*RIGHT +1.15*UP]))
+ para_lab_x.move_to(np.array([1.3*LEFT +1.6*UP]))
+ self.wait()
+ self.play(FadeOut(plane1), FadeOut(plane1_text))
+ self.play(ShowCreation(parabola1))
+ self.add_fixed_in_frame_mobjects(para_lab_x)
+ self.play(ShowCreation(dot1))
+ self.add_fixed_in_frame_mobjects(lab_x)
+ #self.play(ShowCreation(dot1))
+ self.wait()
+ self.play(ShowCreation(line1))
+ self.add_fixed_in_frame_mobjects(tangent_line_x)
+ self.wait()
+
+ self.add_fixed_in_frame_mobjects(text1, brace1, t1)
+ grp1 = VGroup(text1, brace1, t1)
+ grp1.move_to(3*UP+3*RIGHT)
+ self.play(Write(text1),GrowFromCenter(brace1), FadeIn(t1))
+ self.wait()
+ self.play(FadeOut(parabola1), FadeOut(line1), FadeOut(lab_x), FadeOut(para_lab_x), FadeOut(dot1), FadeOut(tangent_line_x),FadeOut(grp1))
+
+
+
+
+ #self.move_camera(phi=80* DEGREES,theta=20*DEGREES)
+
+ self.play(ReplacementTransform(paraboloid_x, paraboloid_copy1))
+ self.wait()
+ self.play(ShowCreation(plane2))
+ self.add_fixed_in_frame_mobjects(plane2_text)
+ self.wait()
+ self.play(ReplacementTransform(paraboloid_copy1, paraboloid_y))
+
+ lab_y.move_to(np.array([1.8*RIGHT +1.15*UP]))
+ para_lab_y.move_to(np.array([1.3*LEFT +1.6*UP]))
+ self.wait()
+ self.play(FadeOut(plane2), FadeOut(plane2_text))
+ self.play(ShowCreation(parabola2))
+ self.add_fixed_in_frame_mobjects(para_lab_y)
+ self.play(ShowCreation(dot2))
+ self.add_fixed_in_frame_mobjects(lab_y)
+ self.wait()
+ self.play(ShowCreation(line2))
+ self.add_fixed_in_frame_mobjects(tangent_line_y)
+ self.wait()
+
+ self.add_fixed_in_frame_mobjects(text2, brace2, t2)
+ grp2 = VGroup(text2, brace2, t2)
+ grp2.move_to(3*UP+3*RIGHT)
+ self.play(Write(text2),GrowFromCenter(brace2), FadeIn(t2))
+ self.wait()
+ self.play(FadeOut(parabola2), FadeOut(line2), FadeOut(lab_y), FadeOut(para_lab_y), FadeOut(dot2), FadeOut(tangent_line_y), FadeOut(grp2))
+ self.wait()
+
+
+ #self.move_camera(phi=80* DEGREES,theta=105*DEGREES)
+ self.play(ReplacementTransform(paraboloid_y, paraboloid_copy2))
+ self.wait()
+
+
+ self.play(ShowCreation(plane1))
+ self.add_fixed_in_frame_mobjects(plane1_text)
+ self.wait()
+ self.play(ReplacementTransform(paraboloid_copy2, paraboloid_x_copy))
+
+ lab_x.move_to(np.array([1.8*RIGHT +1.15*UP]))
+ para_lab_x.move_to(np.array([1.3*LEFT +1.6*UP]))
+ lab_line3.move_to(np.array([2.4*RIGHT +0.5*UP]))
+ self.wait()
+ self.play(FadeOut(plane1), FadeOut(plane1_text))
+ self.play(ShowCreation(parabola1))
+ self.add_fixed_in_frame_mobjects(para_lab_x)
+ self.play(ShowCreation(dot1))
+ self.add_fixed_in_frame_mobjects(lab_x)
+ self.play(ShowCreation(dot3))
+ self.add_fixed_in_frame_mobjects(lab_line3)
+ self.wait()
+ self.play(ShowCreation(line1))
+ self.add_fixed_in_frame_mobjects(tangent_line_x)
+ self.play(ShowCreation(line3))
+ self.wait()
+
+
+ self.add_fixed_in_frame_mobjects(text1,text3)
+ text1.move_to(3*UP+3*RIGHT)
+ text3.next_to(text1, DOWN)
+ self.play(Write(text1),Write(text3))
+ self.wait()
+ self.play(FadeOut(parabola1), FadeOut(line1), FadeOut(lab_x), FadeOut(line3), FadeOut(lab_line3), FadeOut(para_lab_x), FadeOut(dot1), FadeOut(dot3), FadeOut(tangent_line_x), FadeOut(text1), FadeOut(text3))
+ self.wait()
+
+
+
+
+
--
cgit
From 10c4e26b6033ecf3456012e2f586fbc7270c2f62 Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Sat, 4 Jul 2020 12:51:32 +0530
Subject: Delete file3_partial_deriv_defn.gif
---
.../gifs/file3_partial_deriv_defn.gif | Bin 5249722 -> 0 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file3_partial_deriv_defn.gif
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file3_partial_deriv_defn.gif b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file3_partial_deriv_defn.gif
deleted file mode 100644
index 4dd1eee..0000000
Binary files a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file3_partial_deriv_defn.gif and /dev/null differ
--
cgit
From 5e8038a92ef04781b856f5dd598f8a5f82ba90b4 Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Sat, 4 Jul 2020 12:52:35 +0530
Subject: Add files via upload
---
.../gifs/file3_partial_deriv_defn.gif | Bin 0 -> 5249722 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file3_partial_deriv_defn.gif
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file3_partial_deriv_defn.gif b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file3_partial_deriv_defn.gif
new file mode 100644
index 0000000..4dd1eee
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file3_partial_deriv_defn.gif differ
--
cgit
From 69c66cdf3abf38a86aee1336cdc3a0a9c82f043f Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Sat, 4 Jul 2020 13:03:01 +0530
Subject: Delete file7_partial_deriv_clariant_rule.py
---
.../file7_partial_deriv_clariant_rule.py | 108 ---------------------
1 file changed, 108 deletions(-)
delete mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/file7_partial_deriv_clariant_rule.py
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/file7_partial_deriv_clariant_rule.py b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/file7_partial_deriv_clariant_rule.py
deleted file mode 100644
index 313c6cd..0000000
--- a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/file7_partial_deriv_clariant_rule.py
+++ /dev/null
@@ -1,108 +0,0 @@
-from manimlib.imports import *
-
-class ClariantRule(ThreeDScene):
- def construct(self):
- axes = ThreeDAxes()
-
- function = ParametricSurface(
- lambda u, v: np.array([
- 3.5*np.sin(u)*np.cos(v),
- 3.5*np.sin(u)*np.sin(v),
- 3.5*3.5*np.sin(u)*np.sin(u)*(1+2*np.sin(v)*np.sin(v))*np.exp(1 - 3.5*3.5*np.sin(u)*np.sin(u) )
- ]),u_min=0,u_max=PI,v_min=0,v_max=2*PI, color = BLUE_C, fill_color = BLUE_C, fill_opacity = 0.1,
- resolution=(15, 32)).scale(1)
-
-
- function_copy1 = function.copy()
- function_copy2 = function.copy()
-
- func_x =ParametricFunction(
- lambda u : np.array([
- u,
- -1,
- (u*u )*np.exp(1-u*u)
- ]),color=RED_E,t_min=-3.5,t_max=3.5,
- )
-
- func_y =ParametricFunction(
- lambda u : np.array([
- 0,
- u,
- (3*u*u)*np.exp(1-u*u)
- ]),color=PINK,t_min=-3.5,t_max=3.5,
- )
-
- plane_x = Polygon(np.array([-3.5,-1,-3]),np.array([3.5,-1,-3]),np.array([3.5,-1,3]),np.array([-3.5,-1,3]),np.array([-3.5,-1,-3]), color = YELLOW_E, fill_color = YELLOW_B, fill_opacity = 0.1)
- plane_text_x = TextMobject(r"$y = -1$", color = YELLOW_C).move_to(np.array([5,0,2.7])).scale(0.7)
-
- plane_y = Polygon(np.array([0,-3.5,-3]),np.array([0,3.5,-3]),np.array([0,3.5,3]),np.array([0,-3.5,3]),np.array([0,-3.5,-3]), color = GREEN_E, fill_color = GREEN_B, fill_opacity = 0.1)
- plane_text_y = TextMobject(r"$x = 0$", color = GREEN_C).move_to(np.array([0,4,2.7])).scale(0.7)
-
- surface_eqn = TextMobject("Surface", r"$z = (x^2 + 3y^2)e^{(1 - x^2 - y^2)}$", color = YELLOW_C).scale(0.6).move_to(np.array([4.6*LEFT+3.5*UP]))
- surface_eqn[0].set_color(BLUE_C)
-
- self.set_camera_orientation(phi=60 * DEGREES, theta = 45*DEGREES)
-
- self.add(axes)
- axis = TextMobject(r"X",r"Y",r"Z")
- axis[0].move_to(6*RIGHT)
- axis[1].move_to(6*UP)
- axis[2].move_to(np.array([0,0,3.7]))
-
- self.add_fixed_orientation_mobjects(axis[2])
- self.add_fixed_orientation_mobjects(axis[0])
- self.add_fixed_orientation_mobjects(axis[1])
-
- self.play(ShowCreation(function))
-
- self.add_fixed_in_frame_mobjects(surface_eqn)
-
- self.play(ShowCreation(plane_x), ShowCreation(plane_y))
- self.add_fixed_orientation_mobjects(plane_text_x, plane_text_y)
-
- self.play(ShowCreation(func_x), ShowCreation(func_y))
-
- dot_x = Dot().rotate(PI/2).set_color(YELLOW_E)
- alpha_x = ValueTracker(0)
- vector_x = self.get_tangent_vector(alpha_x.get_value(),func_x,scale=1.5)
- dot_x.add_updater(lambda m: m.move_to(vector_x.get_center()))
- self.play(
- ShowCreation(func_x),
- GrowFromCenter(dot_x),
- GrowArrow(vector_x)
- )
- vector_x.add_updater(
- lambda m: m.become(
- self.get_tangent_vector(alpha_x.get_value()%1,func_x,scale=1.5)
- )
- )
- dot_y = Dot().rotate(PI/2).set_color(GREEN_E)
- alpha_y = ValueTracker(0)
- vector_y = self.get_tangent_vector(alpha_y.get_value(),func_y,scale=1.5)
- dot_y.add_updater(lambda m: m.move_to(vector_y.get_center()))
- self.play(
- ShowCreation(func_y),
- GrowFromCenter(dot_y),
- GrowArrow(vector_y)
- )
- vector_y.add_updater(
- lambda m: m.become(
- self.get_tangent_vector(alpha_y.get_value()%1,func_y,scale=1.5)
- )
- )
- self.add(vector_x,dot_x)
-
- self.play(alpha_x.increment_value, 1, run_time=10, rate_func=linear)
-
- self.add(vector_y,dot_y)
- self.play(alpha_y.increment_value, 1, run_time=10, rate_func=linear)
-
- self.wait(2)
-
-
-
-
-
-
-
-
--
cgit
From d553638999c1f6ed2bde0e80042438fc74b18464 Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Sat, 4 Jul 2020 13:03:46 +0530
Subject: Add files via upload
---
.../file7_partial_deriv_clariant_rule.py | 124 +++++++++++++++++++++
1 file changed, 124 insertions(+)
create mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/file7_partial_deriv_clariant_rule.py
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/file7_partial_deriv_clariant_rule.py b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/file7_partial_deriv_clariant_rule.py
new file mode 100644
index 0000000..b48f172
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/file7_partial_deriv_clariant_rule.py
@@ -0,0 +1,124 @@
+from manimlib.imports import *
+
+class ClariantRule(ThreeDScene):
+ def construct(self):
+ axes = ThreeDAxes()
+
+ function = ParametricSurface(
+ lambda u, v: np.array([
+ 3.5*np.sin(u)*np.cos(v),
+ 3.5*np.sin(u)*np.sin(v),
+ 3.5*3.5*np.sin(u)*np.sin(u)*(1+2*np.sin(v)*np.sin(v))*np.exp(1 - 3.5*3.5*np.sin(u)*np.sin(u) )
+ ]),u_min=0,u_max=PI,v_min=0,v_max=2*PI, color = BLUE_C, fill_color = BLUE_C, fill_opacity = 0.1,
+ resolution=(15, 32)).scale(1)
+
+ function_x = ParametricSurface(
+ lambda u, v: np.array([
+ 3.5*np.sin(u)*np.cos(v),
+ 3.5*np.sin(u)*np.sin(v),
+ -4*3.5*3.5*3.5*np.sin(u)*np.sin(u)*np.sin(u)*(2*np.sin(v)*np.sin(v))*np.exp(1 - 3.5*3.5*np.sin(u)*np.sin(u))
+ ]),u_min=0,u_max=PI,v_min=0,v_max=2*PI, color = BLUE_C, fill_color = BLUE_C, fill_opacity = 0.1,
+ resolution=(15, 32)).scale(1)
+
+ func_x =ParametricFunction(
+ lambda u : np.array([
+ u,
+ -1,
+ (u*u )*np.exp(1-u*u)
+ ]),color=RED_E,t_min=-3.5,t_max=3.5,
+ )
+
+ func_y =ParametricFunction(
+ lambda u : np.array([
+ 0,
+ u,
+ (3*u*u)*np.exp(1-u*u)
+ ]),color=PINK,t_min=-3.5,t_max=3.5,
+ )
+
+ plane_x = Polygon(np.array([-3.5,-1,-3]),np.array([3.5,-1,-3]),np.array([3.5,-1,3]),np.array([-3.5,-1,3]),np.array([-3.5,-1,-3]), color = YELLOW_E, fill_color = YELLOW_B, fill_opacity = 0.1)
+ plane_text_x = TextMobject(r"$y = -1$", color = YELLOW_C).move_to(np.array([5,0,2.7])).scale(0.7)
+
+ plane_y = Polygon(np.array([0,-3.5,-3]),np.array([0,3.5,-3]),np.array([0,3.5,3]),np.array([0,-3.5,3]),np.array([0,-3.5,-3]), color = GREEN_E, fill_color = GREEN_B, fill_opacity = 0.1)
+ plane_text_y = TextMobject(r"$x = 0$", color = GREEN_C).move_to(np.array([0,4,2.7])).scale(0.7)
+
+ surface_eqn = TextMobject("Surface", r"$z = f(x,y) = (x^2 + 3y^2)e^{(1 - x^2 - y^2)}$", color = YELLOW_C).scale(0.6).move_to(np.array([4.1*LEFT+3.8*UP]))
+ surface_eqn[0].set_color(BLUE_C)
+ number_plane = NumberPlane()
+
+ line = Line(np.array([0,-1,3]), np.array([0,-1,-3]), color = PURPLE)
+
+ self.set_camera_orientation(phi=60 * DEGREES, theta = 45*DEGREES)
+
+ self.add(axes)
+ axis = TextMobject(r"X",r"Y",r"Z")
+ axis[0].move_to(6*RIGHT)
+ axis[1].move_to(6*UP)
+ axis[2].move_to(np.array([0,0,3.7]))
+
+ self.add_fixed_orientation_mobjects(axis[2])
+ self.add_fixed_orientation_mobjects(axis[0])
+ self.add_fixed_orientation_mobjects(axis[1])
+
+ self.play(ShowCreation(function))
+ self.wait()
+ self.play(ShowCreation(number_plane))
+
+ self.add_fixed_in_frame_mobjects(surface_eqn)
+
+ self.play(ShowCreation(plane_x), ShowCreation(plane_y), ShowCreation(line))
+ self.add_fixed_orientation_mobjects(plane_text_x, plane_text_y)
+
+ self.move_camera(phi=0* DEGREES,theta=45*DEGREES)
+ self.wait(3)
+ self.move_camera(phi=60* DEGREES,theta=45*DEGREES)
+ #self.play(ShowCreation(func_x), ShowCreation(func_y))
+
+ dot_x = Dot().rotate(PI/2).set_color(YELLOW_C)
+ alpha_x = ValueTracker(0)
+ vector_x = self.get_tangent_vector(alpha_x.get_value(),func_x,scale=1.5)
+ dot_x.add_updater(lambda m: m.move_to(vector_x.get_center()))
+ self.play(
+ ShowCreation(func_x),
+ GrowFromCenter(dot_x),
+ GrowArrow(vector_x)
+ )
+ vector_x.add_updater(
+ lambda m: m.become(
+ self.get_tangent_vector(alpha_x.get_value()%1,func_x,scale=1.5)
+ )
+ )
+ dot_y = Dot().rotate(PI/2).set_color(GREEN_E)
+ alpha_y = ValueTracker(0)
+ vector_y = self.get_tangent_vector(alpha_y.get_value(),func_y,scale=1.5)
+ dot_y.add_updater(lambda m: m.move_to(vector_y.get_center()))
+ self.play(
+ ShowCreation(func_y),
+ GrowFromCenter(dot_y),
+ GrowArrow(vector_y)
+ )
+ vector_y.add_updater(
+ lambda m: m.become(
+ self.get_tangent_vector(alpha_y.get_value()%1,func_y,scale=1.5)
+ )
+ )
+ self.add(vector_x,dot_x)
+
+ self.play(alpha_x.increment_value, 1, run_time=5, rate_func=linear)
+
+ self.add(vector_y,dot_y)
+ self.play(alpha_y.increment_value, 1, run_time=5, rate_func=linear)
+
+ self.wait(2)
+
+
+ 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)
+ unit_vector = reference_line.get_unit_vector() * scale
+ vector = Line(coord_i - unit_vector, coord_i + unit_vector, color = ORANGE, buff=0)
+ return vector
+
+
+
--
cgit
From 1059784b8891c73687613cb3c1689b839135b083 Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Sat, 4 Jul 2020 13:06:27 +0530
Subject: Delete file7_partial_deriv_clariant_rule.gif
---
.../gifs/file7_partial_deriv_clariant_rule.gif | Bin 1583937 -> 0 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file7_partial_deriv_clariant_rule.gif
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file7_partial_deriv_clariant_rule.gif b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file7_partial_deriv_clariant_rule.gif
deleted file mode 100644
index 32d5e92..0000000
Binary files a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file7_partial_deriv_clariant_rule.gif and /dev/null differ
--
cgit
From a0e6d42331c1a3eaadcba0c25244589e69871e6b Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Sat, 4 Jul 2020 13:06:50 +0530
Subject: Add files via upload
---
.../gifs/file7_partial_deriv_clariant_rule.gif | Bin 0 -> 7474869 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file7_partial_deriv_clariant_rule.gif
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file7_partial_deriv_clariant_rule.gif b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file7_partial_deriv_clariant_rule.gif
new file mode 100644
index 0000000..ca5beda
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/gifs/file7_partial_deriv_clariant_rule.gif differ
--
cgit
From c6b8ce1e059020bb130522afe9847e6d304b8177 Mon Sep 17 00:00:00 2001
From: Saarth Deshpande
Date: Tue, 7 Jul 2020 14:49:33 +0530
Subject: arcl, velocity changes
---
.../arc-length-and-curvature/file1_arc_length.py | 89 ++++++++++++++++-----
.../file4_curvature_interpretation.py | 16 ++--
.../file2_non_differentiable.py | 36 +++++++++
.../file2_tangent_space_curve.gif | Bin 1317248 -> 0 bytes
.../file2_tangent_space_curve.py | 22 -----
.../file3_tangent_space_curve.gif | Bin 0 -> 1317248 bytes
.../file3_tangent_space_curve.py | 33 ++++++++
7 files changed, 147 insertions(+), 49 deletions(-)
create mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/file2_non_differentiable.py
delete mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/file2_tangent_space_curve.gif
delete mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/file2_tangent_space_curve.py
create mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/file3_tangent_space_curve.gif
create mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/file3_tangent_space_curve.py
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_arc_length.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_arc_length.py
index e295c7a..361e2be 100644
--- a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_arc_length.py
+++ b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_arc_length.py
@@ -1,32 +1,79 @@
from manimlib.imports import *
-class arcl(GraphScene):
- CONFIG = {
- "x_min" : 0,
- "x_max" : 10,
- "y_min" : 0,
- "y_max" : 6,
- "graph_origin": ORIGIN,
- "x_axis_width": 10,
- "y_axis_height": 6 ,
- "x_tick_frequency": 2,
- "y_tick_frequency": 2,
- "Func":lambda x : 1+x**1.3*np.exp(-.12*(x-2)**2)*np.sin(x/4),
- }
+class arcl(MovingCameraScene):
def construct(self):
- self.setup_axes(hideaxes = True)
+ # self.setup()
def curve_(x):
return 3 - (3653*x**2)/5292 + (2477*x**3)/31752 + (13*x**4)/784 - (17*x**5)/5292 + (17*x**6)/63504
curve = FunctionGraph(curve_, x_min=-2, x_max=6, stroke_width = 2, color = BLUE).scale(0.1).move_to(ORIGIN)
- lines = [Line(length = 0.05, color = RED) for i in range(10)]
- lines[0].move_to(np.array([curve_(-2),-2, 0]))
+ lines = [Line(length = 0.05, color = RED).scale(0.2).move_to(ORIGIN).shift(np.array([-4 + 0.1*i, curve_(-2.5 + 0.1*i), 0])).rotate(-25*DEGREES) for i in range(4)]
+ lines2 = [Line(length = 0.05, color = RED).scale(0.2).move_to(ORIGIN).shift(np.array([-4 + 0.125*i, curve_(-2.5 + 0.1*i), 0])).rotate(-25*DEGREES) for i in range(4, 9)]
+ # lines[0].rotate(-25*DEGREES).shift(np.array([-4,curve_(-2.5), 0]))
+ # lines[1].rotate(-25*DEGREES).shift(np.array([-3.78,curve_(-2.3), 0]))
+ # lines3 = [Line(length = 0.05, color = RED).scale(0.2).move_to(ORIGIN + 1.5*UP + 0.6*RIGHT).shift(np.array([-1 + 0.2*i, -1.5 - 0.2*i, 0])).rotate(30*DEGREES) for i in range(4)]
+ # lines2b = VGroup(*lines3).rotate(-8*DEGREES)
+ # lines4 = [Line(length = 0.05, color = RED).scale(0.2).move_to(ORIGIN + 1.6*UP + 0.5*RIGHT).shift(np.array([-1 + 0.18*i, -1.65 - 0.2*i, 0])).rotate(22*DEGREES) for i in range(4, 9)]
+ # lines5 = [Line(length = 0.05, color = RED).scale(0.2).move_to(ORIGIN + 7*RIGHT).shift(np.array([-4 + 0.1*i, curve_(-2.5 + 0.1*i), 0])).rotate(-25*DEGREES) for i in range(4)]
+ # lines6 = [Line(length = 0.05, color = RED).scale(0.2).move_to(ORIGIN +7.25*RIGHT).shift(np.array([-4 + 0.053*i, curve_(-2.5 + 0.1*i), 0])).rotate(-26*DEGREES) for i in range(4, 9)]
+ # lc1 = [Line(length = 0.05, color = RED).scale(0.2).rotate((-25 + i*2) * DEGREES).shift(np.array([-1 + 0.125*i, curve_(-1.5 + 0.1*i), 0])) for i in range(2)]
+ # lc1b = VGroup(*lc1).shift(1.7*LEFT + 0.2*DOWN)
+ text = TextMobject(r'$r(t) = \left\langle t, t^{3} - 2t, 0\right\rangle$ \\ $r\prime (t) = \left\langle 1, 3t^{2} - 2, 0\right\rangle$').scale(0.7).shift(3*UP + 3*LEFT)
- # self.play(FadeIn(curve))
- # self.wait(2)
- self.play(ApplyMethod(curve.scale, 10))
- self.play(FadeIn(VGroup(*lines)))
- self.wait(5)
+ # l = VGroup(*lines, *lines2, lines2b, *lines4, *lines5, *lines6, lc1b).shift(curve.get_center())
+ l = VGroup(*lines, *lines2)
+ arc = Line(lines[3].get_center(), lines2[0].get_center() + np.array([0.005, 0 ,0]), color = GREEN_SCREEN).rotate(12*DEGREES)
+ arctext = TextMobject(r'$ds$', color = GREEN_SCREEN).scale(0.15).next_to(arc.get_center(), 0.001*DOWN + 0.01*RIGHT,buff = 0.01)
+ dy = Arrow(arc.get_start(), np.array([arc.get_start()[0], lines2[0].get_center()[1] + 0.01, 0]), color = YELLOW)
+ dx = Arrow(arc.get_start(), np.array([lines2[0].get_center()[0] - 0.01, arc.get_start()[1], 0]), color = BLUE)
+ dxt = DashedLine(dy.get_end(), dy.get_end() + np.array([0.13, 0 ,0]))
+ dyt = DashedLine(dx.get_end(), dx.get_end() + np.array([0, 0.3 ,0]))
+ dxtext = TextMobject(r'$dx$').scale(0.2).next_to(dx, RIGHT, buff = 0.01)
+ dytext = TextMobject(r'$dy$').scale(0.2).next_to(dy, LEFT, buff = 0.01)
+ formula = TextMobject(r"Using Pythagoras' theorem, \\ $ds = \sqrt{(dx)^{2} + (dy)^{2}}$").scale(0.35).shift(5*LEFT + 0.2*UP)
+
+ compute = TextMobject(r'To compute the arc length from \\ $t = -1.4$ to $t = -1.1$, \\ summation of all small arcs $ds$ \\ is given by $L = \int_{-1.4}^{-1.1} ds$ \\').scale(0.7).shift(6.8*LEFT + 1.5*UP)
+ compute_ = TextMobject(r'L = $ \int_{-1.4}^{-1.1} \sqrt{(\frac{dx}{dt})^{2} + (\frac{dy}{dt})^{2}}\quad dt$ \\ = $\int_{-1.4}^{-1.1} \sqrt{1^{2} + (3t^{2} - 2)^{2}}\quad dt$').scale(0.7).shift(6.8*LEFT + 0.6*DOWN)
+ compute = VGroup(*[compute, compute_])
+ compute2 = TextMobject(r'$ = \int_{-1.4}^{-1.1} \sqrt{9t^{4} - 12t^{2} + 5}\quad dt$').scale(0.7).shift(6.8*LEFT + 1.7*DOWN)
+ compute3 = TextMobject(r'$L = 0.8693$').scale(0.7).shift(6.8*LEFT + 2.2*DOWN)
+
+ dsd = TextMobject(r'We can divide the curve \\ into multiple small arcs $ds$').scale(0.35).shift(5.2*LEFT + 0.2*UP)
+
+ self.play(FadeIn(curve))
+ self.play(ApplyMethod(curve.scale, 10), FadeIn(text))
+ # self.play(FadeIn(l))
+ self.wait(2)
+ self.play(self.camera_frame.set_width, 5,
+ self.camera_frame.move_to, 3.8*LEFT+0.4*DOWN,
+ text.shift, 2.3*LEFT + 2.25*DOWN,
+ text.scale, 0.5, run_time = 4)
+ long = ArcBetweenPoints(lines[1].get_center() + 0.01, lines2[3].get_center(), color = YELLOW, angle = 10*DEGREES).rotate(180*DEGREES)
+ # self.play(ApplyMethod(VGroup(*[curve, l]).scale,0.1, run_time = 4))
+ # self.play(ApplyMethod(VGroup(*[curve, l]).scale,10, run_time = 4))
+ # self.activate_zooming(animate = True)
+
+ self.play(Write(dsd), Write(l))
+ self.wait(2)
+ self.play(FadeOut(dsd), Transform(l, VGroup(*[lines[3], lines2[0]])), FadeIn(VGroup(*[arc, arctext, dy, dx, dxt, dyt, dxtext, dytext])))
+ self.wait(1)
+ self.play(FadeIn(formula))
+ # self.play(FadeIn(VGroup(*[arc, dy, dx, dxt, dyt, dxtext, dytext])))
+ self.wait(2)
+ self.play(FadeOut(VGroup(*[arc, arctext, dy, l, dx, dxt, dyt, dxtext, dytext, formula])))
+ self.play(self.camera_frame.set_width, 15,
+ self.camera_frame.move_to, 3*LEFT,
+ text.shift, 2.5*LEFT + 2.25*UP,
+ text.scale, 2, run_time = 4)
+ self.play(FadeIn(long), FadeIn(compute))
+ self.wait(4)
+ self.play(FadeIn(compute2))
+ self.wait(1)
+ self.play(FadeIn(compute3))
+ # self.play(FadeOut(VGroup(*[curve, arc, dy, dx, dxt, dyt, dxtext, dytext, l])))
+ # self.play(FadeOut(self.zoomed_camera.frame), FadeOut(self.zoomed_display))
+ self.wait(1)
+ self.play(FadeOut(VGroup(*[curve, text, compute, compute2, compute3, long])))
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file4_curvature_interpretation.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file4_curvature_interpretation.py
index 128fc17..f10fa26 100644
--- a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file4_curvature_interpretation.py
+++ b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file4_curvature_interpretation.py
@@ -30,7 +30,7 @@ class interpretation(ZoomedScene):
dsl = TextMobject(r'$ds$', color = GREEN_SCREEN).scale(0.2).next_to(ds, RIGHT, buff = 0)
- tgtText = TextMobject(r'$r\prime (t)$').next_to(tgt, UP, buff = 0).scale(0.7)
+ tgtText = TextMobject(r'$r\prime (t) = \left\langle 1, 2, 0\right\rangle$').next_to(tgt, UP, buff = 0).scale(0.7)
tgt2 = DashedLine((0,0,0),(1, 2, 0), color = GRAY).shift(DOWN + 2*RIGHT)
circle = Circle(radius = 0.9, color = GREEN_SCREEN).shift(0.85*RIGHT + 0.38*DOWN)
circle.set_stroke(opacity = 1)
@@ -49,13 +49,17 @@ class interpretation(ZoomedScene):
"$ds$": GREEN_SCREEN
})
+ main5 = TextMobject(r'$\kappa = 0.357$').scale(0.7).shift(main.get_center() + np.array([2.4,-0.18,0]))
+
nm = Vector((2, -1, 0), color = BLUE).shift(0.005*RIGHT + 0.007*DOWN)
- nmText = TextMobject(r'$r\prime\prime (t)$').next_to(nm, DOWN+RIGHT, buff = 0).scale(0.7)
+ nmText = TextMobject(r'$r\prime\prime (t) = \left\langle 2,0,0\right\rangle$').next_to(nm, DOWN+RIGHT, buff = 0).scale(0.7)
nm2 = DashedLine((0,0,0),(2, -1, 0), color = GRAY).shift(2*UP + RIGHT)
square = Square(fill_color = WHITE, fill_opacity = 0.2).rotate(63*DEGREES).shift(0.5*UP +1.5*RIGHT).scale(1.1)
square.set_stroke(width = 0.1)
+ square2 = Square(fill_color = PINK, fill_opacity = 0.2).scale(0.55).rotate(63*DEGREES).move_to((square.get_center() - dot.get_center()) / 2)
+ square2.set_stroke(width = 0.1)
arrow = CurvedArrow(square.get_center() + np.array([2,1,0]), square.get_center() + np.array([0.5,0,0]))
- arrowText = TextMobject(r'$r\prime (t)\times r\prime\prime (t)$').next_to(arrow.get_start(), DOWN+1*RIGHT, buff = 0).scale(0.7)
+ arrowText = TextMobject(r'$r\prime (t)\times r\prime\prime (t) = 4$').next_to(arrow.get_start(), DOWN+1*RIGHT, buff = 0).scale(0.7)
text1 = TextMobject(r'$\left|\frac{dT}{ds}\right| = \frac{\left|\frac{dT}{dt}\right|}{\left|\frac{ds}{dt}\right|}$').shift(UP+3*LEFT).scale(0.7)
text2 = TextMobject(r'$\left|\frac{dT}{ds}\right| = \frac{\frac{r\prime\prime (t)}{\left| r\prime (t)\right|}\times\frac{r\prime (t)}{\left| r\prime (t)\right|}}{\left|r\prime (t)\right|}$').next_to(text1, DOWN, buff = 0.1).scale(0.7)
@@ -74,7 +78,7 @@ class interpretation(ZoomedScene):
self.play(FadeIn(main2), FadeIn(dot))
self.play(FadeIn(circle), FadeIn(dl), FadeIn(dltext))
self.wait()
- self.play(ReplacementTransform(main2, main3), FadeOut(circle), FadeOut(dl), FadeOut(dltext), FadeIn(VGroup(*[tgt, tgtText])))
+ self.play(ReplacementTransform(main2, main5), FadeIn(main3), FadeOut(circle), FadeOut(dl), FadeOut(dltext), FadeIn(VGroup(*[tgt, tgtText])))
self.wait(1)
self.play(FadeIn(VGroup(*[nm, nmText])))
self.wait(1)
@@ -95,7 +99,7 @@ class interpretation(ZoomedScene):
self.wait(1)
self.play(FadeIn(VGroup(*[square, arrow, arrowText])))
self.wait(1)
- self.play(FadeIn(unit2))
+ self.play(FadeIn(unit2), FadeIn(square2))
self.wait(1)
self.play(FadeIn(VGroup(*[tgt2text, nm2text])))
self.wait(1)
@@ -107,4 +111,4 @@ class interpretation(ZoomedScene):
self.wait(1)
self.play(FadeIn(text4))
self.wait(2)
- self.play(FadeOut(VGroup(*[main, curve, dot, tgt2text, nm2text, text1, text2, text3, text4, tgt, tgtText,nm, nmText,tgt2, nm2,square, arrow, arrowText,unit2])))
+ self.play(FadeOut(VGroup(*[main, main5, square2, curve, dot, tgt2text, nm2text, text1, text2, text3, text4, tgt, tgtText,nm, nmText,tgt2, nm2,square, arrow, arrowText,unit2])))
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/file2_non_differentiable.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/file2_non_differentiable.py
new file mode 100644
index 0000000..a91da6b
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/file2_non_differentiable.py
@@ -0,0 +1,36 @@
+from manimlib.imports import *
+
+class nd(Scene):
+ def construct(self):
+ ld1 = Line().rotate(20*DEGREES)
+ pd1 = Dot(ld1.get_end(), fill_opacity = 0)
+ pd1.set_stroke(width = 0.5)
+ ld2 = Line().rotate(40*DEGREES).shift(1.4*UP + 1.7*RIGHT)
+ pd2 = Dot(ld2.get_start(), fill_opacity = 1, color = PURPLE)
+ t1 = TextMobject('A discontinuous function.').scale(0.7).shift(UP + 2*RIGHT)
+
+ obj1 = VGroup(*[ld1, pd1, ld2, pd2]).shift(4*LEFT)
+ self.play(FadeIn(obj1), FadeIn(t1))
+ self.wait(2)
+
+ ld3 = ld2.copy().rotate(-60*DEGREES).shift(1.4*DOWN + 0.2*RIGHT)
+ pd3 = Dot(ld1.get_end(), fill_opacity = 1, color = PURPLE)
+ t2 = TextMobject('Graph containing a sharp corner.').scale(0.7).shift( 2*RIGHT)
+
+ obj2 = VGroup(*[ld3, pd3])
+
+ self.play(Transform(VGroup(*[ld2, pd2]), obj2), ReplacementTransform(t1, t2))
+
+ self.wait(2)
+
+ ld4 = Line().rotate(90*DEGREES)
+ pd4 = Dot(ld4.get_center(), color = PURPLE)
+ a1 = Arc(start_angle = -180*DEGREES, angle = 90*DEGREES).move_to(ld4.get_end()).rotate(-90*DEGREES).shift(0.5*(UP+RIGHT))
+ a2 = Arc(start_angle = -180*DEGREES, angle = 90*DEGREES).move_to(ld4.get_start()).rotate(90*DEGREES).shift(0.5*(DOWN+LEFT))
+ t3 = TextMobject('Graph with a vertical line.').scale(0.7).shift(2*RIGHT)
+
+ obj3 = VGroup(*[ld4, pd4, a1, a2]).shift(3*LEFT)
+
+ self.play(FadeOut(obj1), Transform(obj2, obj3), ReplacementTransform(t2, t3))
+ self.wait(2)
+ self.play(FadeOut(obj2), FadeOut(t3))
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/file2_tangent_space_curve.gif b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/file2_tangent_space_curve.gif
deleted file mode 100644
index 06ed70f..0000000
Binary files a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/file2_tangent_space_curve.gif and /dev/null differ
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/file2_tangent_space_curve.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/file2_tangent_space_curve.py
deleted file mode 100644
index 67c675e..0000000
--- a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/file2_tangent_space_curve.py
+++ /dev/null
@@ -1,22 +0,0 @@
-from manimlib.imports import *
-
-class tangent(ThreeDScene):
- def construct(self):
- axes = ThreeDAxes()
- self.set_camera_orientation(phi = 125*DEGREES, theta = 135*DEGREES)
- h = ParametricFunction(
- lambda t: np.array([
- 4*(t**3) + 5,
- t**2 + 2*(t**4),
- -2*np.log(2*t)
- ]), t_min = -3, t_max = 1.18
- ).shift(5*LEFT)
- tgtR = Line((4,3,-2*np.log(2)), (19.5, 16, -4.772588), color=YELLOW)
- tgtL =Line((4,3,-2*np.log(2)), (-11.5, -10, 2), color=YELLOW)
- dot = Dot((4,3,-2*np.log(2)), color=RED, radius=0.08)
- self.play(FadeIn(axes),FadeIn(h), FadeIn(dot))
- self.begin_ambient_camera_rotation(rate=0.4)
- self.wait(2)
- self.play(FadeIn(tgtL), FadeIn(tgtR))
- self.wait(5)
- self.play(FadeOut(axes), FadeOut(h), FadeOut(dot), FadeOut(tgtL), FadeOut(tgtR))
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/file3_tangent_space_curve.gif b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/file3_tangent_space_curve.gif
new file mode 100644
index 0000000..06ed70f
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/file3_tangent_space_curve.gif differ
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/file3_tangent_space_curve.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/file3_tangent_space_curve.py
new file mode 100644
index 0000000..c3aecc6
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/file3_tangent_space_curve.py
@@ -0,0 +1,33 @@
+from manimlib.imports import *
+
+class tangent(ThreeDScene):
+ def construct(self):
+ axes = ThreeDAxes()
+ text = TextMobject(r'Tangent', r' to the ', 'space curve', r' \\ at point ', r'$P_{1}$', ' is given by:').scale(0.7).shift(3*UP + 3.5*LEFT)
+ text.set_color_by_tex_to_color_map({
+ "Tangent": YELLOW,
+ '$P_{1}$': RED,
+ 'space curve': BLUE
+ })
+ text.bg=BackgroundRectangle(text,fill_opacity=1, color = BLACK)
+ text_gr =VGroup(text.bg,text)
+ self.set_camera_orientation(phi = 125*DEGREES, theta = 135*DEGREES)
+ h = ParametricFunction(
+ lambda t: np.array([
+ 4*(t**3) + 5,
+ t**2 + 2*(t**4),
+ -2*np.log(2*t)
+ ]), t_min = -3, t_max = 1.18, color = BLUE
+ ).shift(5*LEFT)
+ tgtR = Line((4,3,-2*np.log(2)), (19.5, 16, -4.772588), color=YELLOW)
+ tgtL =Line((4,3,-2*np.log(2)), (-11.5, -10, 2), color=YELLOW)
+ dot = Dot((4,3,-2*np.log(2)), color=RED, radius=0.08)
+ dotl = TextMobject(r'$P_{1}$', color = RED).scale(0.7).shift(2*DOWN + 5*LEFT)
+ self.add_fixed_in_frame_mobjects(text_gr, dotl)
+ self.play(FadeIn(axes),FadeIn(h), FadeIn(dot), FadeIn(dotl))
+ self.wait(2)
+ self.play(FadeIn(tgtL), FadeIn(tgtR))
+ self.begin_ambient_camera_rotation(rate=0.2)
+ self.play(FadeOut(dotl))
+ self.wait(5)
+ self.play(FadeOut(axes), FadeOut(h), FadeOut(text_gr), FadeOut(dot), FadeOut(tgtL), FadeOut(tgtR))
--
cgit
From ab0319a54739b8471de779f55d43091867cac72b Mon Sep 17 00:00:00 2001
From: Saarth Deshpande
Date: Tue, 7 Jul 2020 14:52:22 +0530
Subject: Update README.md
---
.../velocity-and-differentiability/README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/README.md b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/README.md
index bc571c6..02678fd 100644
--- a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/README.md
+++ b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/README.md
@@ -1,2 +1,2 @@
-**file2_tangent_space_curve.py**
-![file2_tangent_space_curve.py](https://raw.githubusercontent.com/saarthdeshpande/FSF-mathematics-python-code-archive/master/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/file2_tangent_space_curve.gif)
+**file3_tangent_space_curve.py**
+![file3_tangent_space_curve.py](https://github.com/saarthdeshpande/FSF-mathematics-python-code-archive/blob/master/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/velocity-and-differentiability/file3_tangent_space_curve.gif)
--
cgit
From 5fce21eac898c754fc661dfdb6162aaafc82b06e Mon Sep 17 00:00:00 2001
From: Saarth Deshpande
Date: Tue, 7 Jul 2020 21:33:20 +0530
Subject: arc length final
---
.../arc-length-and-curvature/file1_arc_length.py | 100 +++++++++++++++------
1 file changed, 72 insertions(+), 28 deletions(-)
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_arc_length.py b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_arc_length.py
index 361e2be..7c970e5 100644
--- a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_arc_length.py
+++ b/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/arc-length-and-curvature/file1_arc_length.py
@@ -21,7 +21,7 @@ class arcl(MovingCameraScene):
# lc1 = [Line(length = 0.05, color = RED).scale(0.2).rotate((-25 + i*2) * DEGREES).shift(np.array([-1 + 0.125*i, curve_(-1.5 + 0.1*i), 0])) for i in range(2)]
# lc1b = VGroup(*lc1).shift(1.7*LEFT + 0.2*DOWN)
- text = TextMobject(r'$r(t) = \left\langle t, t^{3} - 2t, 0\right\rangle$ \\ $r\prime (t) = \left\langle 1, 3t^{2} - 2, 0\right\rangle$').scale(0.7).shift(3*UP + 3*LEFT)
+ text = TextMobject(r'$r(t) = \left\langle t, t^{3} - 2t, 0\right\rangle$ \\ $r\prime (t) = \left\langle 1, 3t^{2} - 2, 0\right\rangle$').scale(0.7).shift(3*UP + 4*RIGHT)
# l = VGroup(*lines, *lines2, lines2b, *lines4, *lines5, *lines6, lc1b).shift(curve.get_center())
l = VGroup(*lines, *lines2)
@@ -33,47 +33,91 @@ class arcl(MovingCameraScene):
dyt = DashedLine(dx.get_end(), dx.get_end() + np.array([0, 0.3 ,0]))
dxtext = TextMobject(r'$dx$').scale(0.2).next_to(dx, RIGHT, buff = 0.01)
dytext = TextMobject(r'$dy$').scale(0.2).next_to(dy, LEFT, buff = 0.01)
- formula = TextMobject(r"Using Pythagoras' theorem, \\ $ds = \sqrt{(dx)^{2} + (dy)^{2}}$").scale(0.35).shift(5*LEFT + 0.2*UP)
+ formula = TextMobject(r"Consider a very small interval ", r'$ds$. \\', r"Using Pythagoras' theorem, \\", r'$ds$', r" = $\sqrt{(dx)^{2} + (dy)^{2}}$").scale(0.25).shift(5*LEFT + 0.5*UP)
+ formula.set_color_by_tex_to_color_map({
+ "$ds$. \\": GREEN_SCREEN,
+ "$ds$": GREEN_SCREEN
+ })
- compute = TextMobject(r'To compute the arc length from \\ $t = -1.4$ to $t = -1.1$, \\ summation of all small arcs $ds$ \\ is given by $L = \int_{-1.4}^{-1.1} ds$ \\').scale(0.7).shift(6.8*LEFT + 1.5*UP)
- compute_ = TextMobject(r'L = $ \int_{-1.4}^{-1.1} \sqrt{(\frac{dx}{dt})^{2} + (\frac{dy}{dt})^{2}}\quad dt$ \\ = $\int_{-1.4}^{-1.1} \sqrt{1^{2} + (3t^{2} - 2)^{2}}\quad dt$').scale(0.7).shift(6.8*LEFT + 0.6*DOWN)
- compute = VGroup(*[compute, compute_])
- compute2 = TextMobject(r'$ = \int_{-1.4}^{-1.1} \sqrt{9t^{4} - 12t^{2} + 5}\quad dt$').scale(0.7).shift(6.8*LEFT + 1.7*DOWN)
- compute3 = TextMobject(r'$L = 0.8693$').scale(0.7).shift(6.8*LEFT + 2.2*DOWN)
+ formula2 = TextMobject(r'To compute the arc length \\ from $a$ to $b$, we need to \\ sum over all intervals ', r'$ds$').scale(0.25).shift(5.2*LEFT + 0.7*UP)
+ formula2.set_color_by_tex_to_color_map({
+ "$ds$": GREEN_SCREEN
+ })
- dsd = TextMobject(r'We can divide the curve \\ into multiple small arcs $ds$').scale(0.35).shift(5.2*LEFT + 0.2*UP)
+ formula3 = TextMobject(r'$L = \int_{a}^{b} ds$ \\ $= \int_{a}^{b} \sqrt{(\frac{dx}{dt})^{2} + (\frac{dy}{dt})^{2} + (\frac{dz}{dt})^{2}}\quad dt$').scale(0.25).shift(5.2*LEFT + 0.1*UP)
- self.play(FadeIn(curve))
+ bl = DashedLine(lines2[4].get_center(), lines2[4].get_center() + np.array([1,0,0]))
+ blt = TextMobject(r'$b$').scale(0.5).next_to(bl.get_center(), DOWN, buff=0.1)
+ al = DashedLine(lines[0].get_center(), lines[0].get_center() + np.array([1,0,0]))
+ alt = TextMobject(r'$a$').scale(0.5).next_to(al.get_center(), UP, buff=0.1)
+ pts = VGroup(*[bl, blt, al, alt])
+
+ compute = TextMobject(r'To compute the arc length from \\ $t = -1.4$ to $t = -1.1$, \\ summation of small intervals $ds$ \\ is given by $L = \int_{-1.4}^{-1.1} ds$ \\').scale(0.7).shift(6.8*LEFT + 2.5*UP)
+ compute_ = TextMobject(r'L = $ \int_{-1.4}^{-1.1} \sqrt{(\frac{dx}{dt})^{2} + (\frac{dy}{dt})^{2} + (\frac{dz}{dt})^{2}}\quad dt$ \\ = $\int_{-1.4}^{-1.1} \sqrt{1^{2} + (3t^{2} - 2)^{2} + 0^{2}}\quad dt$').scale(0.7).shift(6.8*LEFT + -0.6*DOWN)
+ #compute = VGroup(*[compute, compute_])
+ compute2 = TextMobject(r'$ = \int_{-1.4}^{-1.1} \sqrt{9t^{4} - 12t^{2} + 5}\quad dt$').scale(0.7).shift(6.8*LEFT + 0.7*DOWN)
+ compute3 = TextMobject(r'$L = 0.8693$').scale(0.7).shift(6.8*LEFT + 1.2*DOWN)
+ arclen = compute3.copy()
+ arclen = arclen.scale(0.8).next_to(arc.get_center(), RIGHT, buff = 0.1)
+ dsd = TextMobject(r'We can divide the curve \\ into multiple small arcs ', r'$ds$').scale(0.25).shift(5.2*LEFT + 0.2*UP)
+ dsd.set_color_by_tex_to_color_map({
+ "$ds$": GREEN_SCREEN
+ })
+
+ # 13th sec, consider a v small interval ds, show Pythagoras
+ # reduce text size
+ # then show we can divide curve into small ds
+ # all red ds
+ # To compute arc length, we need to sum over all intervals ds
+ # a and b show and give dashes dy dx for first and last
+ # give dz in formula and show it's zero
+ # Zooom out, Remove red bars, draw yellow line
+ # Consider t = -1.4 to -1.1
+ # at end show l = 0.693 near yellow line, smaller size
+
+ ax1 = Vector((0,1,0), color = YELLOW)
+ ax1l = TextMobject(r'$y$').next_to(ax1, LEFT, buff = 0)
+ ax2 = Vector((1,0,0), color = BLUE)
+ ax2l = TextMobject(r'$x$').next_to(ax2, RIGHT, buff = 0)
+ ax = VGroup(*[ax1, ax1l, ax2, ax2l]).scale(0.6).shift(3*DOWN + 6*LEFT)
+
+ self.play(FadeIn(curve), FadeIn(ax))
self.play(ApplyMethod(curve.scale, 10), FadeIn(text))
# self.play(FadeIn(l))
self.wait(2)
+ self.play(FadeOut(text))
self.play(self.camera_frame.set_width, 5,
self.camera_frame.move_to, 3.8*LEFT+0.4*DOWN,
- text.shift, 2.3*LEFT + 2.25*DOWN,
- text.scale, 0.5, run_time = 4)
+ ax.shift, UP,
+ ax.scale, 0.5, run_time = 4)
long = ArcBetweenPoints(lines[1].get_center() + 0.01, lines2[3].get_center(), color = YELLOW, angle = 10*DEGREES).rotate(180*DEGREES)
- # self.play(ApplyMethod(VGroup(*[curve, l]).scale,0.1, run_time = 4))
- # self.play(ApplyMethod(VGroup(*[curve, l]).scale,10, run_time = 4))
- # self.activate_zooming(animate = True)
- self.play(Write(dsd), Write(l))
+
+ self.play(Write(formula),FadeIn(VGroup(*[arc, arctext, dy, dx, dxt, dyt, dxtext, dytext])), FadeIn(VGroup(*[lines[3], lines2[0]])))
self.wait(2)
- self.play(FadeOut(dsd), Transform(l, VGroup(*[lines[3], lines2[0]])), FadeIn(VGroup(*[arc, arctext, dy, dx, dxt, dyt, dxtext, dytext])))
- self.wait(1)
- self.play(FadeIn(formula))
- # self.play(FadeIn(VGroup(*[arc, dy, dx, dxt, dyt, dxtext, dytext])))
+ self.play(ReplacementTransform(formula, dsd), TransformFromCopy(VGroup(*[lines[3], lines2[0]]) , l))
+ #Transform(l, VGroup(*[lines[3], lines2[0]])), )
+ self.wait(2)
+ self.play(ReplacementTransform(dsd, formula2), FadeIn(pts))
+ self.wait(3)
+ self.play(FadeIn(formula3))
self.wait(2)
- self.play(FadeOut(VGroup(*[arc, arctext, dy, l, dx, dxt, dyt, dxtext, dytext, formula])))
- self.play(self.camera_frame.set_width, 15,
+ self.play(FadeOut(VGroup(*[formula3, l, pts, formula2, arc, arctext, dy, dx, dxt, dyt, dxtext, dytext])))
+ self.play(
+ self.camera_frame.set_width, 15,
self.camera_frame.move_to, 3*LEFT,
- text.shift, 2.5*LEFT + 2.25*UP,
- text.scale, 2, run_time = 4)
- self.play(FadeIn(long), FadeIn(compute))
- self.wait(4)
+ ax.shift, DOWN + 3*LEFT,
+ ax.scale, 2.3,
+ run_time = 4)
+ text = text.shift(2*LEFT)
+ self.play(FadeIn(long), FadeIn(compute), FadeIn(text))
+ self.wait(2)
+ self.play(FadeIn(compute_))
+ self.wait(2)
self.play(FadeIn(compute2))
self.wait(1)
self.play(FadeIn(compute3))
- # self.play(FadeOut(VGroup(*[curve, arc, dy, dx, dxt, dyt, dxtext, dytext, l])))
- # self.play(FadeOut(self.zoomed_camera.frame), FadeOut(self.zoomed_display))
self.wait(1)
- self.play(FadeOut(VGroup(*[curve, text, compute, compute2, compute3, long])))
+ self.play(TransformFromCopy(compute3, arclen))
+ self.wait(2)
+ self.play(FadeOut(VGroup(*[ax, arclen, compute_, curve, text, compute, compute2, compute3, long])))
--
cgit
From 18e20980ace4c269bd3d829672ef53a9d2b2ef3f Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Fri, 10 Jul 2020 19:03:40 +0530
Subject: Add files via upload
---
.../directional-derivatives/Directional_Derivatives.pdf | Bin 0 -> 85319 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/directional-derivatives/Directional_Derivatives.pdf
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/directional-derivatives/Directional_Derivatives.pdf b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/directional-derivatives/Directional_Derivatives.pdf
new file mode 100644
index 0000000..342dc80
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/directional-derivatives/Directional_Derivatives.pdf differ
--
cgit
From c55723552bab1faac0fdf9c5eaddda24c82dc2fc Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Fri, 10 Jul 2020 19:04:20 +0530
Subject: Add files via upload
---
.../partial-derivatives/Partial_Derivatives.pdf | Bin 0 -> 97732 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/Partial_Derivatives.pdf
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/Partial_Derivatives.pdf b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/Partial_Derivatives.pdf
new file mode 100644
index 0000000..12559d8
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/Partial_Derivatives.pdf differ
--
cgit
From 71e2d324f507de92f97a96b223e69e0e8da17b48 Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Fri, 10 Jul 2020 19:04:47 +0530
Subject: Delete Multivariable_Functions_Quiz.pdf
---
.../Multivariable_Functions_Quiz.pdf | Bin 109631 -> 0 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/Multivariable_Functions_Quiz.pdf
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/Multivariable_Functions_Quiz.pdf b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/Multivariable_Functions_Quiz.pdf
deleted file mode 100644
index 7895843..0000000
Binary files a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/Multivariable_Functions_Quiz.pdf and /dev/null differ
--
cgit
From 3dc783b7e274aef55572c7642c491229826dc6e6 Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Fri, 10 Jul 2020 19:05:00 +0530
Subject: Add files via upload
---
.../Multivariable_Functions_Quiz.pdf | Bin 0 -> 108179 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/Multivariable_Functions_Quiz.pdf
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/Multivariable_Functions_Quiz.pdf b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/Multivariable_Functions_Quiz.pdf
new file mode 100644
index 0000000..1155206
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/Multivariable_Functions_Quiz.pdf differ
--
cgit
From 9bba6d8d3f567dd5b04d1aedf0d7750a9a2d3eed Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Fri, 10 Jul 2020 19:06:25 +0530
Subject: Delete Multivariable_Functions_Quiz.pdf
---
.../Multivariable_Functions_Quiz.pdf | Bin 108179 -> 0 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/Multivariable_Functions_Quiz.pdf
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/Multivariable_Functions_Quiz.pdf b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/Multivariable_Functions_Quiz.pdf
deleted file mode 100644
index 1155206..0000000
Binary files a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/Multivariable_Functions_Quiz.pdf and /dev/null differ
--
cgit
From db8149cefa1fd09d46b3c6e01810c34c824276d4 Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Fri, 10 Jul 2020 19:06:41 +0530
Subject: Add files via upload
---
.../Multivariable_Functions_Quiz.pdf | Bin 0 -> 108179 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/Multivariable_Functions_Quiz.pdf
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/Multivariable_Functions_Quiz.pdf b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/Multivariable_Functions_Quiz.pdf
new file mode 100644
index 0000000..1155206
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/multivariable-functions/Multivariable_Functions_Quiz.pdf differ
--
cgit
From 6e46f4279b369138ce64218de604b53155cb2778 Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Fri, 10 Jul 2020 19:07:05 +0530
Subject: Delete Partial_Derivatives.pdf
---
.../partial-derivatives/Partial_Derivatives.pdf | Bin 97732 -> 0 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/Partial_Derivatives.pdf
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/Partial_Derivatives.pdf b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/Partial_Derivatives.pdf
deleted file mode 100644
index 12559d8..0000000
Binary files a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/Partial_Derivatives.pdf and /dev/null differ
--
cgit
From 238addb17dc37bcb85dced1d5fb0c9df2d7557a7 Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Fri, 10 Jul 2020 19:07:19 +0530
Subject: Add files via upload
---
.../partial-derivatives/Partial_Derivatives_Quiz.pdf | Bin 0 -> 97732 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/Partial_Derivatives_Quiz.pdf
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/Partial_Derivatives_Quiz.pdf b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/Partial_Derivatives_Quiz.pdf
new file mode 100644
index 0000000..12559d8
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/partial-derivatives/Partial_Derivatives_Quiz.pdf differ
--
cgit
From 54320d558a9603dc990d02d5f55e3d3526fd738e Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Fri, 10 Jul 2020 19:07:37 +0530
Subject: Delete Directional_Derivatives.pdf
---
.../directional-derivatives/Directional_Derivatives.pdf | Bin 85319 -> 0 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/directional-derivatives/Directional_Derivatives.pdf
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/directional-derivatives/Directional_Derivatives.pdf b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/directional-derivatives/Directional_Derivatives.pdf
deleted file mode 100644
index 342dc80..0000000
Binary files a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/directional-derivatives/Directional_Derivatives.pdf and /dev/null differ
--
cgit
From d3c34192339e85bc4a347318f82385849f51a3d7 Mon Sep 17 00:00:00 2001
From: nishanpoojary
Date: Fri, 10 Jul 2020 19:07:52 +0530
Subject: Add files via upload
---
.../Directional_Derivatives_Quiz.pdf | Bin 0 -> 85319 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/directional-derivatives/Directional_Derivatives_Quiz.pdf
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/directional-derivatives/Directional_Derivatives_Quiz.pdf b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/directional-derivatives/Directional_Derivatives_Quiz.pdf
new file mode 100644
index 0000000..342dc80
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/multivariable-functions-and-paritial-derivatives/directional-derivatives/Directional_Derivatives_Quiz.pdf differ
--
cgit
From 20cadd4f6ec5cc626445a8115d4e25083843fe70 Mon Sep 17 00:00:00 2001
From: Saarth Deshpande
Date: Mon, 13 Jul 2020 19:43:48 +0530
Subject: velocity updated, tnb torsion, fs1
---
.../file4_fs1.gif | Bin 551048 -> 0 bytes
.../file4_fs1.py | 104 ++++++++++++++----
.../file5_fs2.gif | Bin 629437 -> 0 bytes
.../file5_fs2.py | 28 -----
.../file6_torsion_intuition.py | 119 +++++++++++++++++++++
5 files changed, 205 insertions(+), 46 deletions(-)
delete mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file4_fs1.gif
delete mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file5_fs2.gif
delete mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file5_fs2.py
create mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file6_torsion_intuition.py
(limited to 'FSF-2020/calculus-of-several-variables')
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
Binary files a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file4_fs1.gif and /dev/null 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
Binary files a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file5_fs2.gif and /dev/null 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
--
cgit
From bf773aca98a71c3d2cd5ff99aac2f2e853456178 Mon Sep 17 00:00:00 2001
From: Saarth Deshpande
Date: Sun, 19 Jul 2020 17:12:03 +0530
Subject: final UPLOAD
---
.../file5_torsion_intuition.py | 119 +++++++++++++
.../file6_fs2.py | 90 ++++++++++
.../file6_torsion_intuition.py | 119 -------------
.../file7_fs3.py | 194 +++++++++++++++++++++
4 files changed, 403 insertions(+), 119 deletions(-)
create mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file5_torsion_intuition.py
create mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file6_fs2.py
delete mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file6_torsion_intuition.py
create mode 100644 FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file7_fs3.py
(limited to 'FSF-2020/calculus-of-several-variables')
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/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
deleted file mode 100644
index 31b9a85..0000000
--- a/FSF-2020/calculus-of-several-variables/geometry-of-planes-and-curves/tnb-frame-and-serret-frenet-formulae/file6_torsion_intuition.py
+++ /dev/null
@@ -1,119 +0,0 @@
-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/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
--
cgit
From bcd70e78f623191176ece96184ec1fa39c6f30b1 Mon Sep 17 00:00:00 2001
From: Padmapriya Mohan
Date: Mon, 20 Jul 2020 14:33:10 +0530
Subject: files with gifs
---
.../Conservative_file1_paths-3d.gif | Bin 0 -> 4409648 bytes
.../Conservative_file1_paths-3d.py | 41 ++++
.../Conservative_file2_line-int.gif | Bin 0 -> 7935159 bytes
.../Conservative_file2_line-int.py | 132 ++++++++++
.../Conservative_file3_path-independent.gif | Bin 0 -> 2453243 bytes
.../Conservative_file3_path-independent.py | 131 ++++++++++
.../Conservative_file4_path-dependent.gif | Bin 0 -> 2476998 bytes
.../Conservative_file4_path-dependent.py | 130 ++++++++++
.../Conservative_file5_closed-loop.gif | Bin 0 -> 1154185 bytes
.../Conservative_file5_closed-loop.py | 63 +++++
.../Conservative_file6_potential-func.gif | Bin 0 -> 3881592 bytes
.../Conservative_file6_potential-func.py | 33 +++
.../Curl and Div/DivCurl_file10_gauss.png | Bin 0 -> 192422 bytes
.../Curl and Div/DivCurl_file10_gauss.py | 51 ++++
.../DivCurl_file11_gravitational-field.png | Bin 0 -> 12102 bytes
.../DivCurl_file11_gravitational-filed.ipynb | 119 +++++++++
.../Curl and Div/DivCurl_file12_ponder-curl.png | Bin 0 -> 34864 bytes
.../Curl and Div/DivCurl_file12_ponder-curl.py | 17 ++
.../DivCurl_file1_sources-and-sinks.gif | Bin 0 -> 17712731 bytes
.../DivCurl_file1_sources-and-sinks.py | 76 ++++++
.../Curl and Div/DivCurl_file2_div-curl-types.py | 162 +++++++++++++
.../Curl and Div/DivCurl_file2_div_curl-types.gif | Bin 0 -> 800 bytes
.../DivCurl_file3_threed-vec-field.gif | Bin 0 -> 3462931 bytes
.../DivCurl_file3_threed-vec-field.ipynb | 67 ++++++
.../Curl and Div/DivCurl_file4_output-curl.gif | Bin 0 -> 1331084 bytes
.../Curl and Div/DivCurl_file4_output-curl.ipynb | 67 ++++++
.../Curl and Div/DivCurl_file5_neg-div.gif | Bin 0 -> 1583652 bytes
.../Curl and Div/DivCurl_file5_neg-div.ipynb | 6 +
.../DivCurl_file6_macro-micro-curl.gif | Bin 0 -> 2824993 bytes
.../Curl and Div/DivCurl_file6_macro-micro-curl.py | 42 ++++
.../Curl and Div/DivCurl_file7_div-formula.gif | Bin 0 -> 1049376 bytes
.../Curl and Div/DivCurl_file7_div-formula.py | 225 +++++++++++++++++
.../Curl and Div/DivCurl_file8_curl-paddle.gif | Bin 0 -> 29737449 bytes
.../Curl and Div/DivCurl_file8_curl-paddle.py | 55 +++++
.../Curl and Div/DivCurl_file9_formal-def.gif | Bin 0 -> 28855629 bytes
.../Curl and Div/DivCurl_file9_formal-def.py | 82 +++++++
.../CurlTheorem_file1_closed-loop.gif | Bin 0 -> 1154185 bytes
.../CurlTheorem_file1_closed-loop.py | 63 +++++
.../CurlTheorem_file2_curl-paddle.gif | Bin 0 -> 29737449 bytes
.../CurlTheorem_file2_curl-paddle.py | 55 +++++
.../CurlTheorem_file3_measure-curl.gif | Bin 0 -> 2952922 bytes
.../CurlTheorem_file3_measure-curl.py | 82 +++++++
.../CurlTheorem_file4_vortex-streamplot.ipynb | 96 ++++++++
.../CurlTheorem_file4_vortex-streamplot.png | Bin 0 -> 80705 bytes
.../CurlTheorem_file5_connected-regions.gif | Bin 0 -> 3364367 bytes
.../CurlTheorem_file5_connected-regions.py | 54 +++++
.../CurlTheorem_file6_not-connected-regions.gif | Bin 0 -> 7740003 bytes
.../CurlTheorem_file6_not-connected-regions.py | 54 +++++
.../Gradient/Gradient_file1_analogy.gif | Bin 0 -> 13662423 bytes
.../Gradient/Gradient_file1_analogy.py | 77 ++++++
.../Gradient/Gradient_file2_input-output.gif | Bin 0 -> 19704445 bytes
.../Gradient/Gradient_file2_input-output.py | 136 +++++++++++
.../Gradient/Gradient_file3_input-output2.gif | Bin 0 -> 17293502 bytes
.../Gradient/Gradient_file3_input-output2.py | 136 +++++++++++
.../Gradient/Gradient_file4_why-partials.gif | Bin 0 -> 17233549 bytes
.../Gradient/Gradient_file4_why-partials.py | 66 +++++
.../Gradient_file5_contour-lines-and-map.ipynb | 104 ++++++++
.../Gradient_file5_contour-lines-and-map.png | Bin 0 -> 57290 bytes
.../Gradient_file6_surf-contour-plot.ipynb | 171 +++++++++++++
.../Gradient/Gradient_file6_surf-contour-plot.png | Bin 0 -> 115964 bytes
.../Gradient/Gradient_file7_missile.py | 45 ++++
.../Gradient/Gradient_file7_missiles.gif | Bin 0 -> 2121832 bytes
.../Gradient/Gradient_file8_fluid-flow.gif | Bin 0 -> 6466207 bytes
.../Gradient/Gradient_file8_fluid-flow.py | 27 +++
.../GreensTheorem_file1_ftc-analogue.gif | Bin 0 -> 1240392 bytes
.../GreensTheorem_file1_ftc-analogue.py | 265 +++++++++++++++++++++
.../GreensTheorem_file2_line-int.gif | Bin 0 -> 7935159 bytes
.../Greens Theorem/GreensTheorem_file2_line-int.py | 132 ++++++++++
.../GreensTheorem_file3_line-int-sum.gif | Bin 0 -> 5780344 bytes
.../GreensTheorem_file3_line-int-sum.py | 211 ++++++++++++++++
.../GreensTheorem_file4_theorem-proof.gif | Bin 0 -> 6082316 bytes
.../GreensTheorem_file4_theorem-proof.py | 184 ++++++++++++++
.../gradient/file1_missile-example.py | 37 ---
.../gradient/file2_gradient-example-1.py | 43 ----
.../gradient/file3_gradient-example-2.py | 39 ---
.../gradient/file4-multidimensional-gradient.py | 113 ---------
.../gradient/file4_gradient-example-3.py | 40 ----
.../gradient/file5_steepest-ascent-analogy.py | 71 ------
.../gradient/file6-maximum.py | 39 ---
79 files changed, 3457 insertions(+), 382 deletions(-)
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file1_paths-3d.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file1_paths-3d.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file2_line-int.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file2_line-int.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file3_path-independent.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file3_path-independent.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file4_path-dependent.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file4_path-dependent.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file5_closed-loop.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file5_closed-loop.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file6_potential-func.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file6_potential-func.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file10_gauss.png
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file10_gauss.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file11_gravitational-field.png
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file11_gravitational-filed.ipynb
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file12_ponder-curl.png
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file12_ponder-curl.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file1_sources-and-sinks.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file1_sources-and-sinks.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file2_div-curl-types.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file2_div_curl-types.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file3_threed-vec-field.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file3_threed-vec-field.ipynb
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file4_output-curl.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file4_output-curl.ipynb
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file5_neg-div.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file5_neg-div.ipynb
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file6_macro-micro-curl.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file6_macro-micro-curl.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file7_div-formula.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file7_div-formula.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file8_curl-paddle.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file8_curl-paddle.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file9_formal-def.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file9_formal-def.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file1_closed-loop.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file1_closed-loop.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file2_curl-paddle.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file2_curl-paddle.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file3_measure-curl.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file3_measure-curl.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file4_vortex-streamplot.ipynb
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file4_vortex-streamplot.png
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file5_connected-regions.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file5_connected-regions.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file6_not-connected-regions.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file6_not-connected-regions.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Gradient/Gradient_file1_analogy.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Gradient/Gradient_file1_analogy.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Gradient/Gradient_file2_input-output.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Gradient/Gradient_file2_input-output.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Gradient/Gradient_file3_input-output2.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Gradient/Gradient_file3_input-output2.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Gradient/Gradient_file4_why-partials.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Gradient/Gradient_file4_why-partials.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Gradient/Gradient_file5_contour-lines-and-map.ipynb
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Gradient/Gradient_file5_contour-lines-and-map.png
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Gradient/Gradient_file6_surf-contour-plot.ipynb
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Gradient/Gradient_file6_surf-contour-plot.png
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Gradient/Gradient_file7_missile.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Gradient/Gradient_file7_missiles.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Gradient/Gradient_file8_fluid-flow.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Gradient/Gradient_file8_fluid-flow.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Greens Theorem/GreensTheorem_file1_ftc-analogue.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Greens Theorem/GreensTheorem_file1_ftc-analogue.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Greens Theorem/GreensTheorem_file2_line-int.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Greens Theorem/GreensTheorem_file2_line-int.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Greens Theorem/GreensTheorem_file3_line-int-sum.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Greens Theorem/GreensTheorem_file3_line-int-sum.py
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Greens Theorem/GreensTheorem_file4_theorem-proof.gif
create mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Greens Theorem/GreensTheorem_file4_theorem-proof.py
delete mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/gradient/file1_missile-example.py
delete mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/gradient/file2_gradient-example-1.py
delete mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/gradient/file3_gradient-example-2.py
delete mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/gradient/file4-multidimensional-gradient.py
delete mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/gradient/file4_gradient-example-3.py
delete mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/gradient/file5_steepest-ascent-analogy.py
delete mode 100644 FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/gradient/file6-maximum.py
(limited to 'FSF-2020/calculus-of-several-variables')
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file1_paths-3d.gif b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file1_paths-3d.gif
new file mode 100644
index 0000000..56c58b1
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file1_paths-3d.gif differ
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file1_paths-3d.py b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file1_paths-3d.py
new file mode 100644
index 0000000..28b2bd4
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file1_paths-3d.py
@@ -0,0 +1,41 @@
+from manimlib.imports import *
+import numpy as np
+
+class routes(ThreeDScene):
+ def construct(self):
+
+ axes = ThreeDAxes()
+ self.begin_ambient_camera_rotation(rate=0.08)
+ self.set_camera_orientation(phi=45 * DEGREES,theta=-65*DEGREES, distance = 45)
+ function = ParametricFunction(
+ lambda t: np.array([
+ 1.5*np.cos(t),
+ 1.5*np.sin(t),
+ t/4
+ ]), t_min = 0, t_max =3*PI).set_color("#0EB1D2")
+
+
+ line = Line(np.array([1.5, 0, 0]), np.array([-1.5, 0, 2.35619])).set_color("#F8F32B")
+
+ dot1 = Sphere(radius = 0.1).move_to(np.array([1.5,0,0])).set_color("#74226C")
+ dot2 = Sphere(radius = 0.1).move_to(np.array([1.5,0,0])).set_color("#74226C")
+
+ label1 = TexMobject(r"A").move_to(np.array([1.5,0,0])).set_color("#FCF7F8")
+ label2 = TexMobject(r"B").move_to(np.array([-1.5,0,2.42])).set_color("#FCF7F8")
+
+ title = TexMobject(r"\textit{Work done}",r"\textit{ against gravity is the}", r"\textit{ same for both paths}").set_color("#F1E3F3").move_to(np.array([0,-3,0]))
+ title[1].set_color("#F8F32B")
+
+ self.add(axes)
+ self.wait()
+ self.play(ShowCreation(function), ShowCreation(line), run_time = 2)
+ self.wait()
+ self.play(MoveAlongPath(dot1, function), run_time = 2)
+ self.wait()
+ self.play(MoveAlongPath(dot2, line), run_time = 1.2)
+ self.wait()
+ self.add_fixed_in_frame_mobjects(title)
+ self.play(Write(title))
+ self.wait()
+
+
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file2_line-int.gif b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file2_line-int.gif
new file mode 100644
index 0000000..22d0509
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file2_line-int.gif differ
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file2_line-int.py b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file2_line-int.py
new file mode 100644
index 0000000..704acf7
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file2_line-int.py
@@ -0,0 +1,132 @@
+from manimlib.imports import *
+
+def field_func(coordinate):
+ x,y = coordinate[:2]
+ return np.array([
+ -x,
+ -y,
+ 0
+ ])
+
+
+class LineIntegral(MovingCameraScene, Scene):
+ def setup(self):
+ MovingCameraScene.setup(self)
+ Scene.setup(self)
+
+ def get_pending(self,path,proportion,dx=0.01):
+ if proportion < 1:
+ coord_i = path.point_from_proportion(proportion)
+ coord_f = path.point_from_proportion(proportion+dx)
+ else:
+ coord_i = path.point_from_proportion(proportion-dx)
+ coord_f = path.point_from_proportion(proportion)
+ line = Line(coord_i,coord_f)
+ angle = line.get_angle()
+ return angle
+
+ def construct(self):
+
+
+ # all the text
+ vec_f = TexMobject(r"\vec F",r" \textit{ is a vector field defined on the plane}").set_color("#EDF2EF")
+ c = TexMobject(r"C",r" \textit{ is a curve on the plane, oriented counter-clockwise.}").set_color("#EDF2EF")
+ dr = TexMobject(r"\vec dr", r"\textit{ gives the direction as we move along C}").set_color("#EDF2EF")
+
+ intg = TexMobject(r"\oint \vec F \cdot \vec dr", r"\textit{ gives the rotation along the curve}").shift(2.5*DOWN).scale(0.7).set_color("#EDF2EF")
+ text = VGroup(vec_f, c, dr).scale(0.6).set_stroke(width = 1.5)
+ text.arrange(DOWN, buff = 0.2)
+ text.shift(3.2*DOWN)
+
+ vec_f[0].set_color("#D1D646")
+ dr[0].set_color("#D1D646")
+ intg[0].set_color("#D1D646")
+
+
+
+
+ self.camera_frame.save_state()
+ vec_f_sym = TexMobject(r"\vec F")
+ c_sym = TexMobject(r"C").move_to(4.8*RIGHT+1.3*UP)
+ dr_sym = TexMobject(r"\vec dr").next_to(vec_f_sym, DOWN, buff = SMALL_BUFF)
+ dp_sym = TexMobject(r"\vec F \cdot \vec dr")
+ intg_sym = TexMobject(r"\oint \vec F \cdot \vec dr")
+
+ symbols = VGroup(vec_f_sym, dr_sym, dp_sym, intg_sym).shift(3*UP).set_color("#D1D646")
+
+
+
+
+ vector_field = VectorField(field_func, x_min = -15, x_max = 15, y_min = -15, y_max = 15).fade(0.5)
+ boundary = Ellipse(width = 9, height = 3).set_color("#32908F")
+ b2 = Ellipse(width = 9, height = 3).set_color(WHITE)
+
+ start_angle = self.get_pending(boundary, 0)
+
+ pointer = Triangle(fill_opacity = 1).set_height(0.25).set_color(WHITE)
+ pointer.set_fill(WHITE)
+ pointer.move_to(boundary.get_start())
+ pointer.rotate(- PI / 2)
+ pointer.save_state()
+ pointer.rotate(start_angle, about_point=pointer.get_center())
+ dp_sym_1 = TexMobject(r"\vec F \cdot \vec dr").next_to(pointer, RIGHT, buff = SMALL_BUFF).scale(0.5).set_color("#D1D646").add_background_rectangle()
+ intg_sym_1 = TexMobject(r"\oint \vec F \cdot \vec dr").next_to(pointer, RIGHT, buff = SMALL_BUFF).scale(0.5).set_color("#75485E").add_background_rectangle()
+ dp = TexMobject(r"\vec F \cdot \vec dr \textit{ measures whether } \vec F \textit{ and } \vec dr", r" \textit{ are oriented the same way }").next_to(dp_sym_1, DOWN, buff = SMALL_BUFF).scale(0.3).set_color("#EDF2EF")
+ dp[1].next_to(dp[0], DOWN, buff = SMALL_BUFF)
+
+
+ # groups according to animation
+ #one = VGroup( vec_f, vec_f_sym)
+ #two = VGroup(boundary, c_sym)
+ #three = VGroup(dr_sym, pointer)
+ #four = VGroup(dp, dp_sym) #this is when to zoom in
+ #five = VGroup(intg, intg_sym)
+
+ delete = VGroup(vec_f, vec_f_sym, c, dr, dr_sym)
+
+
+ self.play(ShowCreation(vec_f), ShowCreation(vec_f_sym))
+ self.wait()
+ self.play(ShowCreation(vector_field), Indicate(vec_f_sym))
+ self.wait(2)
+ self.play(ShowCreation(c))
+ self.wait()
+ self.play(ShowCreation(boundary), ShowCreation(c_sym), Indicate(c))
+ self.wait(2)
+ self.play(ShowCreation(dr))
+ self.wait(2)
+ self.play(ShowCreation(dr_sym), Indicate(dr), ShowCreation(pointer))
+
+ self.play(FadeOut(delete))
+ self.play(
+ self.camera_frame.scale,.25,
+ self.camera_frame.move_to,pointer
+ )
+ self.play(ShowCreation(dp_sym_1), ShowCreation(dp[0]), ShowCreation(dp[1]))
+ self.add(dp_sym)
+ self.wait(3)
+ self.play(Restore(self.camera_frame))
+ self.remove(dp[0], dp[1], dp_sym_1)
+ self.wait()
+ self.add(boundary, pointer, self.camera_frame)
+ def update_rotate_move(mob,alpha):
+ pointer.restore()
+
+ angle = self.get_pending(boundary,alpha)
+
+ pointer.move_to(boundary.point_from_proportion(alpha))
+ pointer.rotate(angle, about_point=pointer.get_center())
+
+
+
+ self.play(
+ #self.camera_frame.scale,.25,
+ UpdateFromAlphaFunc(pointer,update_rotate_move),
+ run_time=3,
+ )
+ self.play(Write(b2))
+ self.play(ReplacementTransform(dp_sym, intg_sym), ShowCreation(intg))
+ self.play(ReplacementTransform(b2, intg_sym))
+ self.play(Indicate(intg_sym))
+ self.wait(2)
+
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file3_path-independent.gif b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file3_path-independent.gif
new file mode 100644
index 0000000..27035d8
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file3_path-independent.gif differ
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file3_path-independent.py b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file3_path-independent.py
new file mode 100644
index 0000000..c662c31
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file3_path-independent.py
@@ -0,0 +1,131 @@
+from manimlib.imports import *
+import numpy as np
+
+def func(coordinate):
+ x,y = coordinate[:2]
+ return np.array([
+ -2*x,
+ -2*y,
+ 0
+ ])
+
+
+
+
+class many_paths(GraphScene):
+ CONFIG = {
+ "x_min" : 0,
+ "x_max" : 8.5,
+ "x_axis_height": 8.5,
+ "y_min" : 0,
+ "y_max" : 8.5,
+ "y_axis_height": 8.5,
+ "graph_origin" : ORIGIN,
+ "function_color" : RED,
+
+ }
+ def construct(self):
+ self.setup_axes(animate=False)
+ self.remove(self.x_axis, self.y_axis)
+ background = VectorField(func,
+ x_min = 0, x_max = 8.5, y_min = 0, y_max = 8.5, colors = ["#DBD8AE"]
+ )
+
+ pointer = Dot(np.array([0, 1.5, 0])).scale(0.7).set_color_by_gradient(["#84732B", YELLOW_E])
+ start = np.array([0, 1.5, 0])
+ end = np.array([7.53, 5.043, 0])
+ path_one= self.get_graph(self.one, x_min = 0, x_max = 7.53)
+ path_two= self.get_graph(self.two, x_min = 0, x_max = 7.53)
+ path_three = self.get_graph(self.three, x_min = 0, x_max = 7.53)
+
+ group = VGroup(path_one, path_two, background, path_three).move_to(np.array([-3,0, 0])).scale(0.75)
+
+
+
+ path_one.set_color("#F6523C")
+ path_two.set_color("#80475E")
+ path_three.set_color("#0F7173")
+
+ # all the text
+ #function = TexMobject(r"f(x,y) = -(x^2 + y^2)").scale(0.6).set_color("#DBD8AE").shift(3.6*UP + 3*LEFT)
+ field = TexMobject(r"\vec F = -2x\hat i - 2y\hat j").set_color("#DBD8AE").shift(3.6*DOWN + 3*LEFT)
+ c1 = TexMobject(r"C_{1}: y = 6sin(\frac{x}{3} + 1.5)").scale(0.7).set_color("#0F7173").shift(3*UP + 4*RIGHT)
+ #c3 = TexMobject(r"C_{3}: y = 6sin(\frac{x}{3} + 1.5)").scale(0.7).set_color("#0F7173").next_to(li_path2, DOWN, buff = LARGE_BUFF)
+ li_path1 = TexMobject(r"\int_{C_{1}} \vec F \cdot \vec dr = ").set_color("#0F7173").next_to(c1, DOWN, buff = 0.2)
+ c2 = TexMobject(r"C_{2}: y = 0.47x + 1.5").scale(0.7).set_color("#80475E").next_to(li_path1, DOWN, buff = 0.4)
+ li_path2 = TexMobject(r"\int_{C_{2}} \vec F \cdot \vec dr = ").set_color("#80475E").next_to(c2, DOWN, buff = 0.2)
+ c3 = TexMobject(r"C_{3}: y = \frac{x^{16}}{2}+ 1.5").scale(0.7).set_color("#F6523C").next_to(li_path2, DOWN, buff = 0.4)
+ li_path3 = TexMobject(r"\int_{C_{3}} \vec F \cdot \vec dr = ").set_color("#F6523C").next_to(c3, DOWN, buff = 0.2)
+
+ cs = VGroup(c1, c2, c3)
+
+
+ c_1 = lambda x: c1_value.get_value()
+ c_2 = lambda x: c2_value.get_value()
+ c_3 = lambda x: c3_value.get_value()
+
+ c1_value = ValueTracker(0)
+ c2_value = ValueTracker(0)
+ c3_value = ValueTracker(0)
+
+ c1_tex = DecimalNumber(c1_value.get_value()).add_updater(lambda v: v.set_value(c1_value.get_value())).next_to(li_path1, RIGHT, buff = SMALL_BUFF).set_color("#0F7173")
+ c2_tex = DecimalNumber(c2_value.get_value()).add_updater(lambda v: v.set_value(c2_value.get_value())).next_to(li_path2, RIGHT, buff = SMALL_BUFF).set_color("#80475E")
+ c3_tex = DecimalNumber(c3_value.get_value()).add_updater(lambda v: v.set_value(c3_value.get_value())).next_to(li_path3, RIGHT, buff = SMALL_BUFF).set_color("#F6523C")
+
+
+ paths = VGroup(li_path1, li_path2, li_path3, c1_tex, c2_tex, c3_tex)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ self.play(ShowCreation(field), ShowCreation(background))
+ self.wait()
+ self.play(ShowCreation(path_one), ShowCreation(path_two), ShowCreation(path_three), ShowCreation(cs))
+ self.wait(2)
+ self.add(c1_tex)
+ self.play(ShowCreation(li_path1))
+ self.play(MoveAlongPath(pointer, path_three), c1_value.set_value,-78.9,
+ rate_func=linear,
+ run_time=3
+ )
+ self.wait(2)
+ self.play(ShowCreation(li_path2))
+ self.add(c2_tex)
+ self.play(MoveAlongPath(pointer, path_two), c2_value.set_value,-78.9,
+ rate_func=linear,
+ run_time=3
+ )
+ self.play(ShowCreation(li_path3))
+ self.add(c3_tex)
+ self.play(MoveAlongPath(pointer, path_one), c3_value.set_value,-78.9,
+ rate_func=linear,
+ run_time=3
+ )
+ self.wait()
+ self.play(Indicate(paths))
+ self.wait()
+ #self.play(MoveAlongPath(pointer, path_three))
+ #self.wait(2)
+
+ def one(self,x):
+ return x**2/16 + 1.5
+
+ def three(self,x):
+ return 6*np.sin(x/3) + 1.5
+
+ def two(self,x):
+ return 0.4705*x + 1.5
+
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file4_path-dependent.gif b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file4_path-dependent.gif
new file mode 100644
index 0000000..d96e1e1
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file4_path-dependent.gif differ
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file4_path-dependent.py b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file4_path-dependent.py
new file mode 100644
index 0000000..cb951e7
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file4_path-dependent.py
@@ -0,0 +1,130 @@
+from manimlib.imports import *
+import numpy as np
+
+def func(coordinate):
+ x,y = coordinate[:2]
+ return np.array([
+ y,
+ -x,
+ 0
+ ])
+
+
+
+
+class many_paths(GraphScene):
+ CONFIG = {
+ "x_min" : 0,
+ "x_max" : 8.5,
+ "x_axis_height": 8.5,
+ "y_min" : 0,
+ "y_max" : 8.5,
+ "y_axis_height": 8.5,
+ "graph_origin" : ORIGIN,
+ "function_color" : RED,
+
+ }
+ def construct(self):
+ self.setup_axes(animate=False)
+ self.remove(self.x_axis, self.y_axis)
+ background = VectorField(func,
+ x_min = 0, x_max = 8.5, y_min = 0, y_max = 8.5, colors = ["#DBD8AE"]
+ )
+
+ pointer = Dot(np.array([0, 1.5, 0])).scale(0.7).set_color_by_gradient(["#84732B", YELLOW_E])
+ start = np.array([0, 1.5, 0])
+ end = np.array([7.53, 5.043, 0])
+ path_one= self.get_graph(self.one, x_min = 0, x_max = 7.53)
+ path_two= self.get_graph(self.two, x_min = 0, x_max = 7.53)
+ path_three = self.get_graph(self.three, x_min = 0, x_max = 7.53)
+
+ group = VGroup(path_one, path_two, background, path_three).move_to(np.array([-3,0, 0])).scale(0.75)
+
+
+
+ path_one.set_color("#F6523C")
+ path_two.set_color("#80475E")
+ path_three.set_color("#0F7173")
+
+ # all the text
+ #function = TexMobject(r"f(x,y) = -(x^2 + y^2)").scale(0.6).set_color("#DBD8AE").shift(3.6*UP + 3*LEFT)
+ field = TexMobject(r"\vec F = y\hat i - x\hat j").set_color("#DBD8AE").shift(3.6*DOWN + 3*LEFT)
+ c1 = TexMobject(r"C_{1}: y = 6sin(\frac{x}{3} + 1.5)").scale(0.7).set_color("#0F7173").shift(3*UP + 4*RIGHT)
+ #c3 = TexMobject(r"C_{3}: y = 6sin(\frac{x}{3} + 1.5)").scale(0.7).set_color("#0F7173").next_to(li_path2, DOWN, buff = LARGE_BUFF)
+ li_path1 = TexMobject(r"\int_{C_{1}} \vec F \cdot \vec dr = ").set_color("#0F7173").next_to(c1, DOWN, buff = 0.2)
+ c2 = TexMobject(r"C_{2}: y = 0.47x + 1.5").scale(0.7).set_color("#80475E").next_to(li_path1, DOWN, buff = 0.4)
+ li_path2 = TexMobject(r"\int_{C_{2}} \vec F \cdot \vec dr = ").set_color("#80475E").next_to(c2, DOWN, buff = 0.2)
+ c3 = TexMobject(r"C_{3}: y = \frac{x^{16}}{2} + 1.5").scale(0.7).set_color("#F6523C").next_to(li_path2, DOWN, buff = 0.4)
+ li_path3 = TexMobject(r"\int_{C_{3}} \vec F \cdot \vec dr = ").set_color("#F6523C").next_to(c3, DOWN, buff = 0.2)
+
+ cs = VGroup(c1, c2, c3)
+
+
+ c_1 = lambda x: c1_value.get_value()
+ c_2 = lambda x: c2_value.get_value()
+ c_3 = lambda x: c3_value.get_value()
+
+ c1_value = ValueTracker(0)
+ c2_value = ValueTracker(0)
+ c3_value = ValueTracker(0)
+
+ c1_tex = DecimalNumber(c1_value.get_value()).add_updater(lambda v: v.set_value(c1_value.get_value())).next_to(li_path1, RIGHT, buff = SMALL_BUFF).set_color("#0F7173")
+ c2_tex = DecimalNumber(c2_value.get_value()).add_updater(lambda v: v.set_value(c2_value.get_value())).next_to(li_path2, RIGHT, buff = SMALL_BUFF).set_color("#80475E")
+ c3_tex = DecimalNumber(c3_value.get_value()).add_updater(lambda v: v.set_value(c3_value.get_value())).next_to(li_path3, RIGHT, buff = SMALL_BUFF).set_color("#F6523C")
+
+
+ paths = VGroup(li_path1, li_path2, li_path3, c1_tex, c2_tex, c3_tex)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ self.play(ShowCreation(field), ShowCreation(background))
+ self.wait()
+ self.play(ShowCreation(path_one), ShowCreation(path_two), ShowCreation(path_three), ShowCreation(cs))
+ self.wait(2)
+ self.add(c1_tex)
+ self.play(ShowCreation(li_path1))
+ self.play(MoveAlongPath(pointer, path_three), c1_value.set_value,-49.67,
+ rate_func=linear,
+ run_time=3
+ )
+ self.wait(2)
+ self.play(ShowCreation(li_path2))
+ self.add(c2_tex)
+ self.play(MoveAlongPath(pointer, path_two), c2_value.set_value,-11.3,
+ rate_func=linear,
+ run_time=3
+ )
+ self.play(ShowCreation(li_path3))
+ self.add(c3_tex)
+ self.play(MoveAlongPath(pointer, path_one), c3_value.set_value,-2.4,
+ rate_func=linear,
+ run_time=3
+ )
+ self.wait()
+ self.play(Indicate(paths))
+ self.wait()
+ #self.play(MoveAlongPath(pointer, path_three))
+ #self.wait(2)
+
+ def one(self,x):
+ return x**2/16 + 1.5
+
+ def three(self,x):
+ return 6*np.sin(x/3) + 1.5
+
+ def two(self,x):
+ return 0.4705*x + 1.5
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file5_closed-loop.gif b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file5_closed-loop.gif
new file mode 100644
index 0000000..87e5dd5
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file5_closed-loop.gif differ
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file5_closed-loop.py b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file5_closed-loop.py
new file mode 100644
index 0000000..9211f0d
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file5_closed-loop.py
@@ -0,0 +1,63 @@
+from manimlib.imports import *
+import numpy as np
+
+def div(coordinate):
+ x,y = coordinate[:2]
+ return np.array([
+ x,
+ y,
+ 0
+ ])
+
+
+class Loop(Scene):
+ def get_pending(self,path,proportion,dx=0.01):
+ if proportion < 1:
+ coord_i = path.point_from_proportion(proportion)
+ coord_f = path.point_from_proportion(proportion+dx)
+ else:
+ coord_i = path.point_from_proportion(proportion-dx)
+ coord_f = path.point_from_proportion(proportion)
+ line = Line(coord_i,coord_f)
+ angle = line.get_angle()
+ return angle
+ def construct(self):
+
+
+
+ boundary = VMobject(stroke_color = "#F4EDED")
+ boundary.set_points_smoothly([np.array([-2, 1.8,0]),np.array([-1.6, 0.5,0]),np.array([-3.2, -1.2,0]),np.array([2.6, -1.5,0]),np.array([1, 0,0]),np.array([3.5,2.3, 0]), np.array([-2,1.8, 0])])
+ #c = TexMobject(r"C").next_to(surf,RIGHT+UP).set_color("#F4EDED")
+
+
+ text = TexMobject(r"\oint \vec F \cdot \vec dr", r" = 0").shift(3*DOWN).set_stroke(width = 1.5)
+ vec_field = VectorField(div)
+
+ start_angle = self.get_pending(boundary, 0)
+
+ pointer = Triangle(fill_opacity = 1).set_height(0.25).set_color(WHITE)
+ pointer.set_fill(WHITE)
+ pointer.move_to(boundary.get_start())
+ pointer.rotate(- PI / 2)
+ pointer.save_state()
+ pointer.rotate(start_angle, about_point=pointer.get_center())
+
+
+ self.play(ShowCreation(boundary), ShowCreation(vec_field))
+ self.wait()
+ self.play(Write(text[0]))
+ def update_rotate_move(mob,alpha):
+ pointer.restore()
+
+ angle = self.get_pending(boundary,alpha)
+
+ pointer.move_to(boundary.point_from_proportion(alpha))
+ pointer.rotate(angle, about_point=pointer.get_center())
+ self.play(
+ #self.camera_frame.scale,.25,
+ UpdateFromAlphaFunc(pointer,update_rotate_move),
+ run_time=3,
+ )
+ self.play(ShowCreation(text[1]))
+ self.play(Indicate(text))
+ self.wait()
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file6_potential-func.gif b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file6_potential-func.gif
new file mode 100644
index 0000000..97a9500
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file6_potential-func.gif differ
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file6_potential-func.py b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file6_potential-func.py
new file mode 100644
index 0000000..e52a03a
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Conservative fields/Conservative_file6_potential-func.py
@@ -0,0 +1,33 @@
+from manimlib.imports import *
+
+def field_func(coordinate):
+ x,y = coordinate[:2]
+ return np.array([
+ np.cos(x),
+ np.cos(y),
+ 0
+ ])
+
+class Potential(ThreeDScene):
+ def construct(self):
+ axes = ThreeDAxes()
+ self.add(axes)
+ self.set_camera_orientation(phi=0*DEGREES,theta=0*DEGREES,distance=40)
+ vec_field = VectorField(field_func, x_min =-3, x_max = 3, y_min =-3, y_max =3)
+ surf = ParametricSurface(lambda u,v: np.array([u,v,
+ np.sin(u) + np.sin(v)]),
+ u_min = -3, u_max = 3, v_min = -3, v_max = 3, stroke_color = PURPLE_E, checkerboard_colors = [PURPLE_E, PURPLE_E]).fade(0.5)
+
+ #text
+ vec = TexMobject(r"\vec F = \cos x \hat i + \cos y \hat j ").set_color(YELLOW_C).shift(3.8*UP+3.6*RIGHT).scale(0.7)
+ func = TexMobject(r"\textit{has a potential function }", r"f(x,y) = \sin x + \sin y").scale(0.7).next_to(vec, DOWN, buff = 0.2)
+ func[1].set_color(PURPLE_E)
+
+ self.play(ShowCreation(vec_field))
+ self.add_fixed_in_frame_mobjects(vec)
+ self.wait()
+ self.play(FadeIn(surf))
+ self.begin_ambient_camera_rotation()
+ self.move_camera(phi=45*DEGREES,theta=60*DEGREES)
+ self.add_fixed_in_frame_mobjects(func)
+ self.wait(2)
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file10_gauss.png b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file10_gauss.png
new file mode 100644
index 0000000..74e2723
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file10_gauss.png differ
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file10_gauss.py b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file10_gauss.py
new file mode 100644
index 0000000..d77f92e
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file10_gauss.py
@@ -0,0 +1,51 @@
+import sys
+import numpy as np
+import matplotlib.pyplot as plt
+from matplotlib.patches import Circle
+
+def E(q, r0, x, y):
+ """Return the electric field vector E=(Ex,Ey) due to charge q at r0."""
+ den = np.hypot(x-r0[0], y-r0[1])**3
+ return q * (x - r0[0]) / den, q * (y - r0[1]) / den
+
+# Grid of x, y points
+nx, ny = 64, 64
+x = np.linspace(-2, 2, nx)
+y = np.linspace(-2, 2, ny)
+X, Y = np.meshgrid(x, y)
+
+# Create a multipole with nq charges of alternating sign, equally spaced
+# on the unit circle.
+nq = 2**int(sys.argv[1])
+charges = []
+for i in range(nq):
+ q = i%2 * 2 - 1
+ charges.append((q, (np.cos(2*np.pi*i/nq), np.sin(2*np.pi*i/nq))))
+
+# Electric field vector, E=(Ex, Ey), as separate components
+Ex, Ey = np.zeros((ny, nx)), np.zeros((ny, nx))
+for charge in charges:
+ ex, ey = E(*charge, x=X, y=Y)
+ Ex += ex
+ Ey += ey
+
+fig = plt.figure()
+plt.rcParams['axes.facecolor'] = 'black'
+ax = fig.add_subplot(111)
+
+# Plot the streamlines with an appropriate colormap and arrow style
+color = 2 * np.log(np.hypot(Ex, Ey))
+ax.streamplot(x, y, Ex, Ey, color=color, linewidth=1, cmap=plt.cm.inferno,
+ density=2, arrowstyle='->', arrowsize=1.5)
+
+# Add filled circles for the charges themselves
+charge_colors = {True: '#aa0000', False: '#0000aa'}
+for q, pos in charges:
+ ax.add_artist(Circle(pos, 0.05, color=charge_colors[q>0]))
+
+ax.set_xlabel('$x$')
+ax.set_ylabel('$y$')
+ax.set_xlim(-2,2)
+ax.set_ylim(-2,2)
+ax.set_aspect('equal')
+plt.show()
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file11_gravitational-field.png b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file11_gravitational-field.png
new file mode 100644
index 0000000..129e51b
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file11_gravitational-field.png differ
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file11_gravitational-filed.ipynb b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file11_gravitational-filed.ipynb
new file mode 100644
index 0000000..4ad8c27
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file11_gravitational-filed.ipynb
@@ -0,0 +1,119 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "%gui qt"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import numpy as np\n",
+ "from mayavi import mlab\n",
+ "import scipy\n",
+ "import time"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/home/padmapriya/mohyavi/lib/python3.6/site-packages/ipykernel_launcher.py:3: RuntimeWarning: invalid value encountered in true_divide\n",
+ " This is separate from the ipykernel package so we can avoid doing imports until\n",
+ "/home/padmapriya/mohyavi/lib/python3.6/site-packages/ipykernel_launcher.py:4: RuntimeWarning: invalid value encountered in true_divide\n",
+ " after removing the cwd from sys.path.\n",
+ "/home/padmapriya/mohyavi/lib/python3.6/site-packages/ipykernel_launcher.py:5: RuntimeWarning: invalid value encountered in true_divide\n",
+ " \"\"\"\n"
+ ]
+ }
+ ],
+ "source": [
+ "x, y, z = np.mgrid[-2:3, -2:3, -2:3]\n",
+ "r = np.sqrt(x**2 + y**2 + z**2)\n",
+ "u = x/r**3\n",
+ "v = y/r**3\n",
+ "w = z/r**3\n",
+ "\n",
+ "a = mlab.quiver3d(x, y, z, u, v, w)\n",
+ "mlab.axes(a)\n",
+ "mlab.show()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "x, y, z = np.mgrid[-2:3, -2:3, -2:3]\n",
+ "u = y**3 - 9*y\n",
+ "v = x**3 - 9*x\n",
+ "w = x\n",
+ "\n",
+ "a = mlab.quiver3d(x, y, z, u, v, w, colormap = 'gist_earth')\n",
+ "mlab.fig(bgcolor = (0,0,0))\n",
+ "\n",
+ "for i in range(50):\n",
+ " mlab.view(65, -65)\n",
+ " mlab.view(azimuth= 3.6*i, elevation=-60, distance=10)\n",
+ " mlab.process_ui_events()\n",
+ " time.sleep = 0.005\n",
+ " mlab.savefig('curl_%02d.png' % i)\n",
+ " \n",
+ "\n",
+ "x, y, z = np.mgrid[-2:3, -2:3, -2:3]\n",
+ "p = x\n",
+ "q = y\n",
+ "r = 4.5*(x**2 - y**2)\n",
+ "\n",
+ "b = mlab.quiver3d(x, y, z, p, q, r, colormap = 'gist_earth')\n",
+ "for j in range(25):\n",
+ " mlab.view(65, -65)\n",
+ " mlab.view(azimuth= 3.6*j, elevation=-60, distance=10)\n",
+ " mlab.process_ui_events()\n",
+ " time.sleep = 0.005\n",
+ " mlab.savefig('curl2_%02d.png' % j)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.9"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file12_ponder-curl.png b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file12_ponder-curl.png
new file mode 100644
index 0000000..2e7fc79
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file12_ponder-curl.png differ
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file12_ponder-curl.py b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file12_ponder-curl.py
new file mode 100644
index 0000000..be8a17a
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file12_ponder-curl.py
@@ -0,0 +1,17 @@
+from manimlib.imports import *
+import numpy as np
+
+def curl(coordinate):
+ x,y = coordinate[:2]
+ return np.array([
+ y,
+ 0,
+ 0
+ ])
+
+class Ponder_curl(Scene):
+ def construct(self):
+ vf = VectorField(curl)
+ self.add(vf)
+ self.wait()
+
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file1_sources-and-sinks.gif b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file1_sources-and-sinks.gif
new file mode 100644
index 0000000..dcc0843
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file1_sources-and-sinks.gif differ
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file1_sources-and-sinks.py b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file1_sources-and-sinks.py
new file mode 100644
index 0000000..d26525e
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file1_sources-and-sinks.py
@@ -0,0 +1,76 @@
+from manimlib.imports import *
+import numpy as np
+
+def divergence(coordinate):
+ x,y = coordinate[:2]
+ return np.array([
+ np.sin(x),
+ np.cos(y),
+ 0
+ ])
+
+def curl(coordinate):
+ x,y = coordinate[:2]
+ return np.array([
+ np.sin(y),
+ np.cos(x),
+ 0
+ ])
+
+class fluid_flow(Scene):
+ def construct(self):
+
+
+
+ ball_a = Dot().set_color_by_gradient(["#F87666", "#F53A23", PURPLE_E]).move_to(np.array([-6,-1,0])).fade(0.2).scale(1.2)
+ ball_b = Dot().set_color_by_gradient(["#F87666", "#F53A23", PURPLE_E]).move_to(np.array([0.1,3,0])).fade(0.2).scale(1.2)
+ ball_c = Dot().set_color_by_gradient(["#F87666", "#F53A23", PURPLE_E]).move_to(np.array([-0.5,-1, 0])).fade(0.2).scale(1.2)
+ ball_d = Dot().set_color_by_gradient(["#F87666", "#F53A23", PURPLE_E]).move_to(np.array([4.5,-1.2,0])).fade(0.2).scale(1.2)
+ ball2 = Dot().set_color_by_gradient(["#F87666", "#F53A23", PURPLE_E]).move_to(np.array([-0.5,0,0])).fade(0.2).scale(1.2)
+ ball3 = Dot().set_color_by_gradient(["#F87666", "#F53A23", PURPLE_E]).move_to(np.array([-1.5,1.2,0])).fade(0.2).scale(1.2)
+ ball4 = Dot().set_color_by_gradient(["#F87666", "#F53A23", PURPLE_E]).move_to(np.array([-1.5,-1.2,0])).fade(0.2).scale(1.2)
+ ball5 = Sphere(radius = 0.2, chekerboard_colors =["#F87666", "#F53A23", PURPLE_E]).set_color_by_gradient(["#F87666", "#F53A23", PURPLE_E]).fade(0.2).move_to(np.array([-4.7,0,0]))
+
+ flow_one = StreamLines(
+ divergence,
+ virtual_time=3,
+ min_magnitude=0,
+ max_magnitude=1,
+ ).set_color_by_gradient(["#003853", "#0478A1","#04AED9", WHITE])
+ flow_div =(AnimatedStreamLines(
+ flow_one,
+ line_anim_class=ShowPassingFlashWithThinningStrokeWidth
+ ))
+
+ flow_two = StreamLines(
+ curl,
+
+ virtual_time=3,
+ min_magnitude=0,
+ max_magnitude=1,
+ ).set_color_by_gradient(["#003853", "#0478A1","#04AED9", WHITE])
+ flow_curl =(AnimatedStreamLines(
+ flow_two,
+ line_anim_class=ShowPassingFlashWithThinningStrokeWidth
+ ))
+
+ label_div = TexMobject(r"\textit{Fluid flows out from }", r"\textit{sources }", r"\textit{and into }", r"\textit{sinks}" ).move_to(np.array([0,3.5, 0])).set_stroke(width = 1.5).scale(0.7)
+ label_div[1].set_color("#F87666")
+ label_div[3].set_color("#F87666")
+ title_div = TexMobject(r"Divergence").set_stroke(width = 1.5).move_to(3*DOWN).set_color("#F87666").scale(1.2)
+ label_curl = TexMobject(r"\textit{Fluid also rotates }", r"\textit{clockwise }", r"\textit{and }", r"\textit{counter-clockwise}" ).move_to(np.array([0,3.5, 0])).set_stroke(width = 1.5).scale(0.7)
+ label_curl[1].set_color("#F87666")
+ label_curl[3].set_color("#F87666")
+ title_curl = TexMobject(r"Curl").set_stroke(width = 1.5).move_to(3*DOWN).set_color("#F87666").scale(1.2)
+
+
+
+
+ self.add(flow_div, label_div)
+ self.play(Write(title_div))
+ self.wait(5)
+ self.remove(flow_div)
+ self.wait()
+ self.add(flow_curl)
+ self.play(ReplacementTransform(label_div, label_curl), ReplacementTransform(title_div, title_curl))
+ self.wait(6)
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file2_div-curl-types.py b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file2_div-curl-types.py
new file mode 100644
index 0000000..e8e1a83
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file2_div-curl-types.py
@@ -0,0 +1,162 @@
+from manimlib.imports import *
+import numpy as np
+
+def pos_div(coordinate):
+ x,y = coordinate[:2]
+ return np.array([
+ x,
+ y,
+ 0
+ ])
+
+def neg_div(coordinate):
+ x,y = coordinate[:2]
+ return np.array([
+ -x,
+ -y,
+ 0
+ ])
+
+def zero_div(coordinate):
+ x,y = coordinate[:2]
+ y = 1.0
+ return np.array([
+ y,
+ 0,
+ 0
+ ])
+
+def curl_c(coordinate):
+ x,y = coordinate[:2]
+ return np.array([
+ y,
+ -x,
+ 0
+ ])
+
+def curl_ac(coordinate):
+ x,y = coordinate[:2]
+ return np.array([
+ -y,
+ x,
+ 0
+ ])
+
+
+
+
+class Examples(Scene):
+ def construct(self):
+
+ vf1 = VectorField(pos_div, x_min = -1.5, x_max = 1.5, y_min = -1.5, y_max = 1.5).shift(2.5*UP, 4*LEFT)
+ vf3 = VectorField(neg_div, x_min = -1.5, x_max = 1.5, y_min = -1.5, y_max = 1.5).shift(2.5*UP, 4*RIGHT)
+ vf2 = VectorField(zero_div, x_min = -1.5, x_max = 1.5, y_min = -1.5, y_max = 1.5).move_to(np.array([0, 0.5, 0]))
+ vf4 = VectorField(curl_c, x_min = -1.5, x_max = 1.5, y_min = -1.5, y_max = 1.5).shift(2*DOWN, 4*RIGHT)
+ vf5 = VectorField(curl_ac, x_min = -1.5, x_max = 1.5, y_min = -1.5, y_max = 1.5).shift(2*DOWN, 4*LEFT)
+ dot = Dot().move_to(vf1.get_center())
+ label3 = TexMobject(r"\textit{Sink}", r"\textrm{div} F < 0").set_color(BLUE_E).scale(0.6).shift(3*DOWN + 0.7*RIGHT)
+ label1 = TexMobject(r"\textit{Source}", r"\textrm{div} F > 0").set_color(YELLOW_E).scale(0.6).shift(2.8*DOWN + 0.7*RIGHT)
+ label2 = TexMobject(r"\textrm{div} F =0", r"\textrm{ curl} F = 0").scale(0.6).shift(3*DOWN + 0.7*RIGHT)
+ label4 = TexMobject(r"\textit{Clockwise rotation}", r"\textrm{curl} F < 0").set_color(BLUE_E).scale(0.6).shift(3*DOWN + 0.7*RIGHT)
+ label5 = TexMobject(r"\textit{Counter-clockwise rotation}", r"\textrm{curl} F > 0").set_color(YELLOW_E).scale(0.6).shift(3*DOWN + 0.7*RIGHT)
+
+ label1[1].next_to(label1[0], DOWN, buff = SMALL_BUFF).set_color(WHITE)
+ label2[1].next_to(label2[0], DOWN, buff = SMALL_BUFF).set_color(WHITE)
+ label3[1].next_to(label3[0], DOWN, buff = SMALL_BUFF).set_color(WHITE)
+
+ label4[1].next_to(label4[0], DOWN, buff = SMALL_BUFF).set_color(WHITE)
+ label5[1].next_to(label5[0], DOWN, buff = SMALL_BUFF).set_color(WHITE)
+
+ lines_a = StreamLines(
+ pos_div,
+ virtual_time=1.5,
+ min_magnitude=0,
+ max_magnitude=1.5,
+ x_min = -1, x_max = 1, y_min = -1, y_max = 1
+ ).shift(2.5*UP, 4*LEFT)
+ lines1 = AnimatedStreamLines(
+ lines_a,
+ line_anim_class=ShowPassingFlashWithThinningStrokeWidth
+ )
+
+ lines_b = StreamLines(
+ zero_div,
+ virtual_time=1.5,
+ min_magnitude=0,
+ max_magnitude=1.5,
+ x_min = -0.5, x_max = 0.5, y_min = -0.5, y_max = 0.5
+ ).move_to(np.array([-0.2, 0.5, 0]))
+ lines2 = AnimatedStreamLines(
+ lines_b,
+ line_anim_class=ShowPassingFlashWithThinningStrokeWidth
+ )
+
+ lines_c = StreamLines(
+ neg_div,
+ virtual_time=1.5,
+ min_magnitude=0,
+ max_magnitude=1.5,
+ x_min = -1, x_max = 1, y_min = -1, y_max = 1
+ ).shift(2.5*UP, 4*RIGHT)
+ lines3 =(AnimatedStreamLines(
+ lines_c,
+ line_anim_class=ShowPassingFlashWithThinningStrokeWidth
+ ))
+
+ lines_d = StreamLines(
+ curl_c,
+ virtual_time=1.5,
+ min_magnitude=0,
+ max_magnitude=1.5,
+ x_min = -1, x_max = 1, y_min = -1, y_max = 1
+ ).shift(2*DOWN, 4*RIGHT)
+ lines4 =(AnimatedStreamLines(
+ lines_d,
+ line_anim_class=ShowPassingFlashWithThinningStrokeWidth
+ ))
+
+ lines_e = StreamLines(
+ curl_ac,
+ virtual_time=1.5,
+ min_magnitude=0,
+ max_magnitude=1.5,
+ x_min = -1, x_max = 1, y_min = -1, y_max = 1
+ ).shift(2*DOWN, 4*LEFT)
+ lines5 =(AnimatedStreamLines(
+ lines_e,
+ line_anim_class=ShowPassingFlashWithThinningStrokeWidth
+ ))
+ self.play(Write(vf1))
+ self.wait()
+ self.add(lines1)
+ self.play(ShowCreation(label1[0]), ShowCreation(label1[1]))
+ self.wait(4)
+ self.remove(lines1)
+ self.play(Write(vf2))
+ self.add(lines2)
+ self.play(ReplacementTransform(label1, label2))
+ self.play(Indicate(label2))
+ self.wait(4)
+ self.remove(lines2)
+ self.play(Write(vf3))
+ self.add(lines3)
+ self.play(ReplacementTransform(label2, label3))
+ self.play(Indicate(label3))
+ self.wait(4)
+ self.remove(lines3)
+ self.play(Write(vf4))
+ self.add(lines4)
+ self.play(ReplacementTransform(label3, label4))
+ self.play(Indicate(label4))
+ self.wait(4)
+ self.remove(lines4)
+ self.play(Write(vf5))
+ self.add(lines5)
+ self.play(ReplacementTransform(label4, label5))
+ self.play(Indicate(label5))
+ self.wait(4)
+ self.remove(lines5)
+ self.wait()
+
+
+
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file2_div_curl-types.gif b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file2_div_curl-types.gif
new file mode 100644
index 0000000..9d60f45
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file2_div_curl-types.gif differ
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file3_threed-vec-field.gif b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file3_threed-vec-field.gif
new file mode 100644
index 0000000..ad331a3
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file3_threed-vec-field.gif differ
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file3_threed-vec-field.ipynb b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file3_threed-vec-field.ipynb
new file mode 100644
index 0000000..8d41df4
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file3_threed-vec-field.ipynb
@@ -0,0 +1,67 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "%gui qt"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import numpy as np\n",
+ "from mayavi import mlab"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "x, y, z = np.mgrid[-2:3, -2:3, -2:3]\n",
+ "u = y**3 - 9*y\n",
+ "v = x**3 - 9*x\n",
+ "w = x\n",
+ "\n",
+ "a = mlab.quiver3d(x, y, z, u, v, w)\n",
+ "mlab.axes(a)\n",
+ "mlab.show()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.9"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file4_output-curl.gif b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file4_output-curl.gif
new file mode 100644
index 0000000..956458b
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file4_output-curl.gif differ
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file4_output-curl.ipynb b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file4_output-curl.ipynb
new file mode 100644
index 0000000..0f8b326
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file4_output-curl.ipynb
@@ -0,0 +1,67 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "%gui qt"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import numpy as np\n",
+ "from mayavi import mlab"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "x, y, z = np.mgrid[-2:3, -2:3, -2:3]\n",
+ "u = x\n",
+ "v = y\n",
+ "w = 4.5*(x**2 - y**2)\n",
+ "\n",
+ "a = mlab.quiver3d(x, y, z, u, v, w)\n",
+ "mlab.axes(a)\n",
+ "mlab.show()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.9"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file5_neg-div.gif b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file5_neg-div.gif
new file mode 100644
index 0000000..7634acf
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file5_neg-div.gif differ
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file5_neg-div.ipynb b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file5_neg-div.ipynb
new file mode 100644
index 0000000..7fec515
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file5_neg-div.ipynb
@@ -0,0 +1,6 @@
+{
+ "cells": [],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file6_macro-micro-curl.gif b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file6_macro-micro-curl.gif
new file mode 100644
index 0000000..9b30ce5
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file6_macro-micro-curl.gif differ
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file6_macro-micro-curl.py b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file6_macro-micro-curl.py
new file mode 100644
index 0000000..02c75a3
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file6_macro-micro-curl.py
@@ -0,0 +1,42 @@
+from manimlib.imports import *
+import numpy as np
+
+def curl(coordinate):
+ x,y = coordinate[:2]
+ return np.array([
+ -y,
+ x,
+ 0
+ ])
+
+
+class Subtle(Scene):
+ def construct(self):
+ vf1 = VectorField(curl)
+ pinwheel = SVGMobject("geo").move_to(np.array([2, 0, 0])).scale(0.3).set_stroke(width = 0.3).set_color_by_gradient(["#adf802", YELLOW_C]).move_to(np.array([2.3, 0, 0]))
+ self.add(pinwheel)
+
+ label1 = TexMobject(r"\textit{Microscopic curl}").shift(3*DOWN).add_background_rectangle()
+ label2 = TexMobject(r"\textit{Macroscopic curl}").shift(3*DOWN)
+
+ ball1 = Dot(checkerboard_colors = [BLUE_E, PURPLE_E], resolution = [2,2], radius = 0.4).move_to(np.array([-1, -1, 0]))
+ ball2 = Sphere(checkerboard_colors = [BLUE_E, TEAL], resolution = [16, 16], radius = 0.3).move_to(np.array([2, 0, 0]))
+ circ = Circle(radius = 2)
+
+
+ self.add(vf1)
+ self.wait()
+ self.play(ShowCreation(pinwheel))
+ self.bring_to_front(pinwheel)
+ self.play(Rotating(pinwheel), ShowCreation(label1))
+ self.wait(2)
+ #self.add(ball1)
+ move_submobjects_along_vector_field(pinwheel, curl)
+ self.play(FadeOut(label1), ShowCreation(label2))
+ self.play(Indicate(label2))
+
+ self.wait(5)
+
+
+
+
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file7_div-formula.gif b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file7_div-formula.gif
new file mode 100644
index 0000000..4910d2f
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file7_div-formula.gif differ
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file7_div-formula.py b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file7_div-formula.py
new file mode 100644
index 0000000..4e1eab2
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file7_div-formula.py
@@ -0,0 +1,225 @@
+from manimlib.imports import *
+import numpy as np
+
+def div(coordinate):
+ x,y = coordinate[:2]
+ return np.array([
+ x,
+ y,
+ 0
+ ])
+
+
+
+
+class Grid(VMobject):
+ CONFIG = {
+ "height": 6.0,
+ "width": 6.0,
+ }
+
+ def __init__(self, rows, columns, **kwargs):
+ digest_config(self, kwargs, locals())
+ VMobject.__init__(self, **kwargs)
+
+ def generate_points(self):
+ x_step = self.width / self.columns
+ y_step = self.height / self.rows
+
+ for x in np.arange(0, self.width + x_step, x_step):
+ self.add(Line(
+ [x - self.width / 2., -self.height / 2., 0],
+ [x - self.width / 2., self.height / 2., 0],
+ ))
+ for y in np.arange(0, self.height + y_step, y_step):
+ self.add(Line(
+ [-self.width / 2., y - self.height / 2., 0],
+ [self.width / 2., y - self.height / 2., 0]
+ ))
+
+
+class ScreenGrid(VGroup):
+ CONFIG = {
+ "rows":8,
+ "columns":14,
+ "height": FRAME_Y_RADIUS*2,
+ "width": 14,
+ "grid_stroke":0.5,
+ "grid_color":WHITE,
+ "axis_color":RED,
+ "axis_stroke":2,
+ "show_points":False,
+ "point_radius":0,
+ "labels_scale":0.5,
+ "labels_buff":0,
+ "number_decimals":2
+ }
+
+ def __init__(self,**kwargs):
+ VGroup.__init__(self,**kwargs)
+ rows=self.rows
+ columns=self.columns
+ grilla=Grid(width=self.width,height=self.height,rows=rows,columns=columns).set_stroke(self.grid_color,self.grid_stroke)
+
+ vector_ii=ORIGIN+np.array((-self.width/2,-self.height/2,0))
+ vector_id=ORIGIN+np.array((self.width/2,-self.height/2,0))
+ vector_si=ORIGIN+np.array((-self.width/2,self.height/2,0))
+ vector_sd=ORIGIN+np.array((self.width/2,self.height/2,0))
+
+ ejes_x=Line(LEFT*self.width/2,RIGHT*self.width/2)
+ ejes_y=Line(DOWN*self.height/2,UP*self.height/2)
+
+ ejes=VGroup(ejes_x,ejes_y).set_stroke(self.axis_color,self.axis_stroke)
+
+ divisiones_x=self.width/columns
+ divisiones_y=self.height/rows
+
+ direcciones_buff_x=[UP,DOWN]
+ direcciones_buff_y=[RIGHT,LEFT]
+ dd_buff=[direcciones_buff_x,direcciones_buff_y]
+ vectores_inicio_x=[vector_ii,vector_si]
+ vectores_inicio_y=[vector_si,vector_sd]
+ vectores_inicio=[vectores_inicio_x,vectores_inicio_y]
+ tam_buff=[0,0]
+ divisiones=[divisiones_x,divisiones_y]
+ orientaciones=[RIGHT,DOWN]
+ puntos=VGroup()
+ leyendas=VGroup()
+
+
+ for tipo,division,orientacion,coordenada,vi_c,d_buff in zip([columns,rows],divisiones,orientaciones,[0,1],vectores_inicio,dd_buff):
+ for i in range(1,tipo):
+ for v_i,direcciones_buff in zip(vi_c,d_buff):
+ ubicacion=v_i+orientacion*division*i
+ punto=Dot(ubicacion,radius=self.point_radius)
+ coord=round(punto.get_center()[coordenada],self.number_decimals)
+ leyenda=TextMobject("%s"%coord).scale(self.labels_scale)
+ leyenda.next_to(punto,direcciones_buff,buff=self.labels_buff)
+ puntos.add(punto)
+ leyendas.add(leyenda)
+
+ self.add(grilla,ejes,leyendas)
+ if self.show_points==True:
+ self.add(puntos)
+
+
+
+
+
+
+class ExpDiv(Scene):
+ def construct(self):
+
+ #all the text
+ field_text = TexMobject(r"\vec F = P\hat i + Q\hat j").shift(3*UP+5*RIGHT)
+ field_text_2 = TexMobject(r"\vec F = 2x\hat i + 2y\hat j").shift(3*UP+5*RIGHT)
+ p = TexMobject(r"P = 2x").scale(0.8)
+ q = TexMobject(r"Q = 2y").next_to(p, RIGHT).scale(0.8)
+ pq = VGroup(p, q)
+ pq.next_to(field_text_2, DOWN, buff = SMALL_BUFF)
+ dpq = TexMobject(r"\frac{\partial P}{\partial x}", r" \frac{\partial Q}{\partial y}").scale(0.8).next_to(pq, DOWN, buff = LARGE_BUFF)
+
+
+ dp_dq = TexMobject(r"\frac{\partial P}{\partial x} + \frac{\partial Q}{\partial y}", r" = \textrm{div} \vec F").scale(0.8).next_to(pq, DOWN, buff = LARGE_BUFF)
+ #dp_dq1 = TexMobject(r" = \textrm{div} \vec F").scale(0.8)
+ #dp_dq1.next_to(dp_dq[0], DOWN, buff = SMALL_BUFF)
+ dp_text = TexMobject(r"\frac{\partial P}{\partial x}\textit{: the rate of change of the horizontal component as x increases}").shift(3*DOWN).scale(0.8)
+ dq_text = TexMobject(r"\frac{\partial Q}{\partial y}\textit{: the rate of change of the vertical component as y increases}").shift(3*DOWN).scale(0.8)
+
+
+ vector_field = VectorField(div, x_min = -4, x_max = 4, y_min = -4, y_max = 4).shift(1.5*LEFT)
+
+ x_comps=VGroup()
+ y_comps=VGroup()
+ for vector in vector_field:
+ x = Vector(RIGHT, color = BLUE_E)
+ y = Vector(UP, color= YELLOW_E)
+ x.put_start_and_end_on(vector.points[0], np.array([vector.get_end()[0],vector.points[0][1],0]))
+ y.put_start_and_end_on(vector.points[0], np.array([vector.points[0][0],vector.get_end()[1],0]))
+ x_comps.add(x)
+ y_comps.add(y)
+
+ line1 = Arrow(4*LEFT, 4*RIGHT).shift(3.5*DOWN+1.5*LEFT)
+ line2 = Arrow(4*DOWN, 4*UP).shift(3*RIGHT)
+
+
+
+
+ # f(x) = x**2
+ fx = lambda x: x.get_value()/10
+ # ValueTrackers definition
+ x_value = ValueTracker(-4)
+ fx_value = ValueTracker(fx(x_value))
+ # DecimalNumber definition
+ x_tex = DecimalNumber(x_value.get_value()).add_updater(lambda v: v.set_value(x_value.get_value()))
+ fx_tex = DecimalNumber(fx_value.get_value()).add_updater(lambda v: v.set_value(fx(x_value)))
+ # TeX labels definition
+ x_label = TexMobject("x = ")
+ fx_label = TexMobject("P = ")
+ # Grouping of labels and numbers
+ group = VGroup(x_tex,fx_tex,x_label,fx_label).scale(0.8)
+ VGroup(x_tex, fx_tex).arrange_submobjects(DOWN,buff=0.3)
+ # Align labels and numbers
+ x_label.next_to(x_tex,LEFT, buff=0.1,aligned_edge=x_label.get_bottom())
+ fx_label.next_to(fx_tex,LEFT, buff=0.1,aligned_edge=fx_label.get_bottom())
+
+
+ fy = lambda y: y.get_value()/10
+ # ValueTrackers definition
+ y_value = ValueTracker(-4)
+ fy_value = ValueTracker(fy(y_value))
+ # DecimalNumber definition
+ y_tex = DecimalNumber(y_value.get_value()).add_updater(lambda v: v.set_value(y_value.get_value()))
+ fy_tex = DecimalNumber(fy_value.get_value()).add_updater(lambda v: v.set_value(fy(y_value)))
+ # Tey labels definition
+ y_label = TexMobject("y = ")
+ fy_label = TexMobject("Q = ")
+ # Grouping of labels and numbers
+ group_2 = VGroup(y_tex,fy_tex,y_label,fy_label).scale(0.8)
+ VGroup(y_tex, fy_tex).arrange_submobjects(DOWN,buff=0.3)
+ # Align labels and numbers
+ y_label.next_to(y_tex,LEFT, buff=0.1,aligned_edge=y_label.get_bottom())
+ fy_label.next_to(fy_tex,LEFT, buff=0.1,aligned_edge=fy_label.get_bottom())
+
+
+ self.play(ShowCreation(field_text))
+ self.wait()
+ self.play(ShowCreation(vector_field), ReplacementTransform(field_text, field_text_2))
+ self.wait()
+ self.play(ShowCreation(p), ShowCreation(q), FadeOut(vector_field))
+ self.wait()
+ self.play(ShowCreation(dpq[0]), ShowCreation(x_comps))
+ self.play(Indicate(dpq[0]))
+ self.wait()
+ self.play(ShowCreation(dp_text))
+ self.wait()
+ self.play(Uncreate(dp_text))
+
+ self.add(group.move_to(5*RIGHT+3*DOWN))
+ self.play(Write(line1),
+ x_value.set_value,4,
+ rate_func=linear,
+ run_time=3
+ )
+ self.wait(2)
+ self.play(FadeOut(group), FadeOut(line1), ApplyFunction(lambda a:a.fade(), x_comps))
+
+ self.play(ShowCreation(dpq[1]), ShowCreation(y_comps))
+ self.play(Indicate(dpq[1]))
+ self.wait(2)
+ self.play(ShowCreation(dq_text))
+ self.wait()
+ self.play(Uncreate(dq_text))
+
+ self.add(group_2.move_to(5*RIGHT+3*DOWN))
+ self.play(Write(line2),
+ y_value.set_value,4,
+ rate_func=linear,
+ run_time=3
+ )
+ self.wait(2)
+ self.play(ReplacementTransform(dpq, dp_dq), FadeOut(line2), ReplacementTransform(x_comps, vector_field), ReplacementTransform(y_comps, vector_field), FadeOut(group_2))
+
+ self.play(Indicate(dp_dq))
+ self.wait()
+
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file8_curl-paddle.gif b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file8_curl-paddle.gif
new file mode 100644
index 0000000..41db451
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file8_curl-paddle.gif differ
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file8_curl-paddle.py b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file8_curl-paddle.py
new file mode 100644
index 0000000..7a11992
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file8_curl-paddle.py
@@ -0,0 +1,55 @@
+from manimlib.imports import *
+
+def field_func(coordinate):
+ x,y = coordinate[:2]
+ return np.array([
+ -y,
+ x,
+ 0
+ ])
+
+class Paddlewheel(ThreeDScene):
+ def construct(self):
+ axes = ThreeDAxes()
+ #self.add(axes)
+ text = TextMobject("Insert the paddle into the flow of water").shift(3*DOWN).add_background_rectangle()
+ text_a = TextMobject("The rotation of the wheel is proportional to the component of curl in the direction of the axle").shift(3*DOWN).scale(0.7)
+
+ vec_field = VectorField(field_func, x_min =-4, x_max = 4, y_min =-4, y_max =4)
+
+ self.set_camera_orientation(phi=0*DEGREES,theta=0*DEGREES,distance=40)
+ lines_a = StreamLines(
+ field_func,
+ virtual_time=3,
+ min_magnitude=0,
+ max_magnitude=3,
+ ).set_color_by_gradient([WHITE, BLUE_E])
+ flow = AnimatedStreamLines(
+ lines_a,
+ line_anim_class=ShowPassingFlashWithThinningStrokeWidth
+ )
+
+ paddle = VGroup(Line(np.array([3, 0, 0]), np.array([-3, 0, 0])),
+ Line(np.array([0, 3, 0]), np.array([0, -3, 0]))).set_stroke(width = 8).set_color(YELLOW_E)
+ cylinder = ParametricSurface(
+ lambda u, v: np.array([
+ 0.1*np.cos(u),
+ 0.1*np.sin(u),
+ v,
+ ]),
+ u_min = 0, u_max = 2*np.pi, v_min = -0.2, v_max = 3.5, checkerboard_colors = [YELLOW_E, YELLOW_E]).fade(0.5)
+ plane = ParametricSurface(lambda u, v: np.array([u, v, 0]), checkerboard_colors = [WHITE, WHITE]).fade(0.9)
+
+ self.add(paddle, cylinder, flow)
+ self.add_fixed_in_frame_mobjects(text)
+ self.play(Rotating(paddle))
+ self.wait()
+ self.play(FadeIn(vec_field))
+ self.remove(flow, text)
+ self.bring_to_front(cylinder)
+ #self.play(Rotating(paddle))
+ self.wait()
+ self.add_fixed_in_frame_mobjects(text_a)
+ #self.play(ReplacementTransform(text, text_a))
+ self.move_camera(phi=60*DEGREES,theta=30*DEGREES)
+ self.wait()
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file9_formal-def.gif b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file9_formal-def.gif
new file mode 100644
index 0000000..6247aea
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file9_formal-def.gif differ
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file9_formal-def.py b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file9_formal-def.py
new file mode 100644
index 0000000..ecafca4
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file9_formal-def.py
@@ -0,0 +1,82 @@
+from manimlib.imports import *
+import numpy as np
+
+
+
+def func(coordinate):
+ x,y = coordinate[:2]
+ return np.array([
+ 1.9*np.cos(x+2*y),
+ 1.5*np.sin(x-2*y),
+ 0
+ ])
+
+def coord(x,y,z=0):
+ return np.array([x,y,z])
+
+class Instrument(Scene):
+ CONFIG = {
+ "x_coords": ([1, 2.2, 3.9, 3, -0, -0.2, 1]),
+ "y_coords": ([1.5, 1, -0.5, -2.0, -1.4, 0.5, 1.5]),
+ }
+
+ def setup(self):
+ self.tuples = list(zip(self.x_coords,self.y_coords))
+ dots = self.get_all_mobs()
+
+ def get_dots(self, coords):
+ dots = VGroup(*[Dot(coord(x,y)) for x,y in coords])
+ return dots
+
+ def get_all_mobs(self):
+ dots = self.get_dots(self.tuples)
+ return dots
+
+
+class Curl_one(MovingCameraScene, Instrument):
+ def setup(self):
+ MovingCameraScene.setup(self)
+ Instrument.setup(self)
+
+
+ def construct(self):
+ vec = VectorField(func)
+
+
+ frame_one = Circle(radius = 0.5).move_to(np.array([4, 2, 0]))
+ dot = Dot(frame_one.get_center()).scale(0.5)
+ surface = VMobject()
+ surface.set_points_smoothly([*[coord(x,y) for x,y in self.tuples]])
+ surface.move_to(dot.get_center()).set_stroke(width = 0.5)
+
+ label = TexMobject(r"A").scale(0.5).next_to(dot, LEFT+UP, buff = SMALL_BUFF)
+ #self.add(frame_one)
+ self.camera_frame.save_state()
+ self.play(
+ self.camera_frame.set_width,frame_one.get_width()*7.0,
+ self.camera_frame.move_to,frame_one)
+
+
+
+
+ self.add(vec, dot, label)
+ lines = StreamLines(
+ func,
+ virtual_time=7,
+ min_magnitude=0,
+ max_magnitude=8,
+ )
+ lines1 = AnimatedStreamLines(
+ lines,
+ line_anim_class=ShowPassingFlashWithThinningStrokeWidth
+ )
+
+ self.add(lines1)
+ self.wait(3)
+ self.play(Restore(self.camera_frame))
+ self.wait(2)
+ self.add(surface)
+ self.wait(3)
+ self.play(ApplyMethod(surface.scale, 0.01), run_time = 2)
+ self.remove(surface)
+ self.wait(2)
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file1_closed-loop.gif b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file1_closed-loop.gif
new file mode 100644
index 0000000..87e5dd5
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file1_closed-loop.gif differ
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file1_closed-loop.py b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file1_closed-loop.py
new file mode 100644
index 0000000..9211f0d
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file1_closed-loop.py
@@ -0,0 +1,63 @@
+from manimlib.imports import *
+import numpy as np
+
+def div(coordinate):
+ x,y = coordinate[:2]
+ return np.array([
+ x,
+ y,
+ 0
+ ])
+
+
+class Loop(Scene):
+ def get_pending(self,path,proportion,dx=0.01):
+ if proportion < 1:
+ coord_i = path.point_from_proportion(proportion)
+ coord_f = path.point_from_proportion(proportion+dx)
+ else:
+ coord_i = path.point_from_proportion(proportion-dx)
+ coord_f = path.point_from_proportion(proportion)
+ line = Line(coord_i,coord_f)
+ angle = line.get_angle()
+ return angle
+ def construct(self):
+
+
+
+ boundary = VMobject(stroke_color = "#F4EDED")
+ boundary.set_points_smoothly([np.array([-2, 1.8,0]),np.array([-1.6, 0.5,0]),np.array([-3.2, -1.2,0]),np.array([2.6, -1.5,0]),np.array([1, 0,0]),np.array([3.5,2.3, 0]), np.array([-2,1.8, 0])])
+ #c = TexMobject(r"C").next_to(surf,RIGHT+UP).set_color("#F4EDED")
+
+
+ text = TexMobject(r"\oint \vec F \cdot \vec dr", r" = 0").shift(3*DOWN).set_stroke(width = 1.5)
+ vec_field = VectorField(div)
+
+ start_angle = self.get_pending(boundary, 0)
+
+ pointer = Triangle(fill_opacity = 1).set_height(0.25).set_color(WHITE)
+ pointer.set_fill(WHITE)
+ pointer.move_to(boundary.get_start())
+ pointer.rotate(- PI / 2)
+ pointer.save_state()
+ pointer.rotate(start_angle, about_point=pointer.get_center())
+
+
+ self.play(ShowCreation(boundary), ShowCreation(vec_field))
+ self.wait()
+ self.play(Write(text[0]))
+ def update_rotate_move(mob,alpha):
+ pointer.restore()
+
+ angle = self.get_pending(boundary,alpha)
+
+ pointer.move_to(boundary.point_from_proportion(alpha))
+ pointer.rotate(angle, about_point=pointer.get_center())
+ self.play(
+ #self.camera_frame.scale,.25,
+ UpdateFromAlphaFunc(pointer,update_rotate_move),
+ run_time=3,
+ )
+ self.play(ShowCreation(text[1]))
+ self.play(Indicate(text))
+ self.wait()
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file2_curl-paddle.gif b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file2_curl-paddle.gif
new file mode 100644
index 0000000..41db451
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file2_curl-paddle.gif differ
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file2_curl-paddle.py b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file2_curl-paddle.py
new file mode 100644
index 0000000..7a11992
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file2_curl-paddle.py
@@ -0,0 +1,55 @@
+from manimlib.imports import *
+
+def field_func(coordinate):
+ x,y = coordinate[:2]
+ return np.array([
+ -y,
+ x,
+ 0
+ ])
+
+class Paddlewheel(ThreeDScene):
+ def construct(self):
+ axes = ThreeDAxes()
+ #self.add(axes)
+ text = TextMobject("Insert the paddle into the flow of water").shift(3*DOWN).add_background_rectangle()
+ text_a = TextMobject("The rotation of the wheel is proportional to the component of curl in the direction of the axle").shift(3*DOWN).scale(0.7)
+
+ vec_field = VectorField(field_func, x_min =-4, x_max = 4, y_min =-4, y_max =4)
+
+ self.set_camera_orientation(phi=0*DEGREES,theta=0*DEGREES,distance=40)
+ lines_a = StreamLines(
+ field_func,
+ virtual_time=3,
+ min_magnitude=0,
+ max_magnitude=3,
+ ).set_color_by_gradient([WHITE, BLUE_E])
+ flow = AnimatedStreamLines(
+ lines_a,
+ line_anim_class=ShowPassingFlashWithThinningStrokeWidth
+ )
+
+ paddle = VGroup(Line(np.array([3, 0, 0]), np.array([-3, 0, 0])),
+ Line(np.array([0, 3, 0]), np.array([0, -3, 0]))).set_stroke(width = 8).set_color(YELLOW_E)
+ cylinder = ParametricSurface(
+ lambda u, v: np.array([
+ 0.1*np.cos(u),
+ 0.1*np.sin(u),
+ v,
+ ]),
+ u_min = 0, u_max = 2*np.pi, v_min = -0.2, v_max = 3.5, checkerboard_colors = [YELLOW_E, YELLOW_E]).fade(0.5)
+ plane = ParametricSurface(lambda u, v: np.array([u, v, 0]), checkerboard_colors = [WHITE, WHITE]).fade(0.9)
+
+ self.add(paddle, cylinder, flow)
+ self.add_fixed_in_frame_mobjects(text)
+ self.play(Rotating(paddle))
+ self.wait()
+ self.play(FadeIn(vec_field))
+ self.remove(flow, text)
+ self.bring_to_front(cylinder)
+ #self.play(Rotating(paddle))
+ self.wait()
+ self.add_fixed_in_frame_mobjects(text_a)
+ #self.play(ReplacementTransform(text, text_a))
+ self.move_camera(phi=60*DEGREES,theta=30*DEGREES)
+ self.wait()
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file3_measure-curl.gif b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file3_measure-curl.gif
new file mode 100644
index 0000000..4e6a7e8
Binary files /dev/null and b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file3_measure-curl.gif differ
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file3_measure-curl.py b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file3_measure-curl.py
new file mode 100644
index 0000000..e7a324d
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file3_measure-curl.py
@@ -0,0 +1,82 @@
+from manimlib.imports import *
+
+def field_func(coordinate):
+ x,y = coordinate[:2]
+ return np.array([
+ -y,
+ x,
+ 0
+ ])
+
+
+class LineIntegral(MovingCameraScene, Scene):
+ def setup(self):
+ MovingCameraScene.setup(self)
+ Scene.setup(self)
+
+ def get_pending(self,path,proportion,dx=0.01):
+ if proportion < 1:
+ coord_i = path.point_from_proportion(proportion)
+ coord_f = path.point_from_proportion(proportion+dx)
+ else:
+ coord_i = path.point_from_proportion(proportion-dx)
+ coord_f = path.point_from_proportion(proportion)
+ line = Line(coord_i,coord_f)
+ angle = line.get_angle()
+ return angle
+
+ def construct(self):
+
+ vector_field = VectorField(field_func)
+ vec_field_for_flow = VectorField(field_func, x_min = -1.5, x_max = 1.5, y_min = -1.5, y_max = 1.5)
+ flow_rep = StreamLines(
+ field_func,
+ virtual_time=4,
+ min_magnitude=0,
+ max_magnitude=2,
+ dt = 0.1,
+ x_min = -1, x_max = 1, y_min = -1, y_max = 1,
+ ).set_color_by_gradient([BLUE_E, TEAL, WHITE])
+ flow = AnimatedStreamLines(
+ flow_rep,
+ line_anim_class=ShowPassingFlashWithThinningStrokeWidth
+ )
+ boundary = Circle(radius = 2).set_color("#7FFF00")
+
+ start_angle = self.get_pending(boundary, 0)
+
+ pointer = Triangle(fill_opacity = 1).set_height(0.25).set_color("#ffff00")
+ pointer.set_fill("#ffff00")
+ pointer.move_to(boundary.get_start())
+ pointer.rotate(- PI / 2)
+ pointer.save_state()
+ pointer.rotate(start_angle, about_point=pointer.get_center())
+ sym_1 = TexMobject(r"\oint \vec F \cdot \vec dr").next_to(pointer, RIGHT, buff = SMALL_BUFF).scale(0.7).set_color("#ffff00").add_background_rectangle()
+ sym_2 = TexMobject(r"\nabla \times \vec F").scale(0.7).set_color(TEAL).add_background_rectangle()
+
+ self.play(ShowCreation(vector_field))
+ self.wait()
+ self.add(flow)
+ self.play(Write(boundary), Write(sym_2))
+ self.wait(2)
+ self.play(Write(pointer))
+ def update_rotate_move(mob,alpha):
+ pointer.restore()
+
+ angle = self.get_pending(boundary,alpha)
+
+ pointer.move_to(boundary.point_from_proportion(alpha))
+ pointer.rotate(angle, about_point=pointer.get_center())
+
+
+
+ self.play(
+ #self.camera_frame.scale,.25,
+ UpdateFromAlphaFunc(pointer,update_rotate_move),
+ run_time=3,
+ )
+ self.play(Write(sym_1))
+ self.wait()
+
+
+
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file4_vortex-streamplot.ipynb b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file4_vortex-streamplot.ipynb
new file mode 100644
index 0000000..81f17a5
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and conservative fields/CurlTheorem_file4_vortex-streamplot.ipynb
@@ -0,0 +1,96 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/home/padmapriya/.local/lib/python3.6/site-packages/ipykernel_launcher.py:4: RuntimeWarning: invalid value encountered in true_divide\n",
+ " after removing the cwd from sys.path.\n",
+ "/home/padmapriya/.local/lib/python3.6/site-packages/ipykernel_launcher.py:5: RuntimeWarning: invalid value encountered in true_divide\n",
+ " \"\"\"\n"
+ ]
+ },
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ "