diff options
author | Somnath Pandit | 2020-06-19 21:16:20 +0530 |
---|---|---|
committer | Somnath Pandit | 2020-06-19 21:16:20 +0530 |
commit | dd361296965480c0c94b6ae035e7bdd898b112a4 (patch) | |
tree | 36008c749f694d01b8142a3c926f58f47e23b858 /FSF-2020/calculus-of-several-variables | |
parent | f4e9b0f92f0e2af217e133dd928b12421ace28b6 (diff) | |
download | FSF-mathematics-python-code-archive-dd361296965480c0c94b6ae035e7bdd898b112a4.tar.gz FSF-mathematics-python-code-archive-dd361296965480c0c94b6ae035e7bdd898b112a4.tar.bz2 FSF-mathematics-python-code-archive-dd361296965480c0c94b6ae035e7bdd898b112a4.zip |
new animation
Diffstat (limited to 'FSF-2020/calculus-of-several-variables')
2 files changed, 350 insertions, 0 deletions
diff --git a/FSF-2020/calculus-of-several-variables/integrals-of-multivariable-functions/vector-fields/file1_vector_fields.gif b/FSF-2020/calculus-of-several-variables/integrals-of-multivariable-functions/vector-fields/file1_vector_fields.gif Binary files differnew file mode 100644 index 0000000..96e50ac --- /dev/null +++ b/FSF-2020/calculus-of-several-variables/integrals-of-multivariable-functions/vector-fields/file1_vector_fields.gif diff --git a/FSF-2020/calculus-of-several-variables/integrals-of-multivariable-functions/vector-fields/file1_vector_fields.py b/FSF-2020/calculus-of-several-variables/integrals-of-multivariable-functions/vector-fields/file1_vector_fields.py new file mode 100644 index 0000000..6b1b686 --- /dev/null +++ b/FSF-2020/calculus-of-several-variables/integrals-of-multivariable-functions/vector-fields/file1_vector_fields.py @@ -0,0 +1,350 @@ +from manimlib.imports import * + +class VectorFields(ThreeDScene): + + CONFIG = { + "axes_config": { + "x_min": -4, + "x_max": 4, + "y_min": -4, + "y_max": 4, + "z_min": -3, + "z_max": 3, + "a":-4 ,"b": 4, "c":-4 , "d":4, + "axes_shift": ORIGIN+2*LEFT, + "x_axis_config": { + "tick_frequency": 1, + # "include_tip": False, + }, + "y_axis_config": { + "tick_frequency": 1, + # "include_tip": False, + }, + "z_axis_config": { + "tick_frequency": 1, + # "include_tip": False, + }, + "num_axis_pieces": 10, + }, + "default_graph_style": { + "stroke_width": 2, + "stroke_color": WHITE, + }, + "default_vector_field_config": { + "delta_x": .5, + "delta_y": .5, + "x_min": -3, + "x_max": 3, + "y_min": -3, + "y_max": 3, + "min_magnitude": 0, + "max_magnitude": 4, + "colors": [BLUE,GREEN,ORANGE,RED], + "length_func": lambda norm : .45*sigmoid(norm), + "opacity": 1.0, + "vector_config": { + "stroke_width":3.5, + "max_tip_length_to_length_ratio": 0.35, + "max_stroke_width_to_length_ratio": 8, + }, + }, + + } + + + def construct(self): + + self.setup_axes() + axes=self.axes + + self.set_camera_orientation(distance=35, + phi=0 * DEGREES, + theta=-90 * DEGREES, + ) + self.move_camera(frame_center=axes.c2p(0,0,0)) + + self.show_2d_field() + self.wait(3) + + self.show_3d_field() + self.begin_ambient_camera_rotation(rate=-.3,) + self.wait(1.5) + axes.x_axis.rotate( + -90 * DEGREES, LEFT, + about_point=axes.c2p(0, 0, 0), + ), + axes.y_axis.rotate( + 90 * DEGREES, UP, + about_point=axes.c2p(0, 0, 0), + ), + self.move_camera( + # distance=20, + phi=85 * DEGREES, + rate_func=linear, + run_time=8 + ) + self.wait(5) + + + def show_2d_field(self): + d2_field_text=TexMobject( + r"\vec F(x,y)=-y\hat i+x\hat j", + stroke_width=1.5 + ).set_color_by_gradient( + *self.default_vector_field_config["colors"] + ) + d2_field_text.to_corner(UR,buff=.5) + + d2_field = self.get_vector_field( + lambda v: np.array([ + -v[1], + v[0], + 0 + ]), + ) + self.add_fixed_in_frame_mobjects(d2_field_text) + # self.add(d2_field) + self.play(Write(d2_field_text)) + self.play(FadeIn(d2_field)) + + self.d2_field=d2_field + self.d2_field_text=d2_field_text + + def show_3d_field(self): + d3_field_text=TexMobject( + r"\vec F(x,y,z)=-y\hat i+x\hat j+0 \hat k", + stroke_width=1.5 + ).set_color_by_gradient( + *self.default_vector_field_config["colors"] + ) + d3_field_text.to_corner(UR,buff=.5) + + d3_field= self.get_vector_field( + lambda v: np.array([ + -v[1], + v[0], + 0 + # v[0]*v[2] + ]), + z_min=-2, + z_max= 2, + delta_x= 1, + delta_y= 1, + delta_z= 1, + length_func=lambda norm : .5*sigmoid(norm), + opacity= 1, + ThreeD=True + ) + + self.remove(self.d2_field,self.d2_field_text) + self.add_fixed_in_frame_mobjects(d3_field_text) + # self.add(d3_field) + self.play(Write(d3_field_text)) + self.play(FadeIn(d3_field)) + + def get_vector_field(self,func,ThreeD=False,**kwargs): + config = dict() + config.update(self.default_vector_field_config) + config.update(kwargs) + if ThreeD: + vector_field= VectorField3D(func,**config) + else: + vector_field= VectorField(func,**config) + + vector_field.move_to(self.axes.c2p(0,0,0)) + self.vector_field=vector_field + + return vector_field + + + +#------------------------------------------------------- + #customize 3D axes + def get_three_d_axes(self, include_labels=True, include_numbers=False, **kwargs): + config = dict(self.axes_config) + config.update(kwargs) + axes = ThreeDAxes(**config) + axes.set_stroke(width=2) + self.axes=axes + + if include_numbers: + self.add_axes_numbers(axes) + + if include_labels: + self.add_axes_labels(axes) + + # Adjust axis orientation + axes.x_axis.rotate( + -0 * DEGREES, LEFT, + about_point=axes.c2p(0, 0, 0), + ) + axes.y_axis.rotate( + 0 * DEGREES, UP, + about_point=axes.c2p(0, 0, 0), + ) + + return axes + + + def setup_axes(self): + axes = self.get_three_d_axes(include_labels=True) + axes.scale(1) + # axes.center() + axes.shift(axes.axes_shift) + + self.add(axes) + self.axes = axes + + def add_axes_numbers(self, axes): + x_axis = axes.x_axis + y_axis = axes.y_axis + tex_vals_x = [ + + ("1", axes.b), + ] + tex_vals_y=[ + + ("1", axes.d) + ] + x_labels = VGroup() + y_labels = VGroup() + for tex, val in tex_vals_x: + label = TexMobject(tex) + label.scale(1) + label.next_to(x_axis.n2p(val), DOWN) + # label.rotate(180 * DEGREES) + x_labels.add(label) + x_axis.add(x_labels) + x_axis.numbers = x_labels + + for tex, val in tex_vals_y: + label = TexMobject(tex) + label.scale(1) + label.next_to(y_axis.n2p(val), LEFT) + label.rotate(90 * DEGREES) + y_labels.add(label) + + y_axis.add(y_labels) + y_axis.numbers = y_labels + + return axes + + def add_axes_labels(self, axes): + x_label = TexMobject("x") + x_label.next_to(axes.x_axis.get_end(), RIGHT) + axes.x_axis.label = x_label + + y_label = TextMobject("y") + y_label.rotate(90 * DEGREES, OUT) + y_label.next_to(axes.y_axis.get_end(), UP) + axes.y_axis.label = y_label + + z_label = TextMobject("z") + z_label.rotate(90 * DEGREES, RIGHT) + z_label.next_to(axes.z_axis.get_zenith(), LEFT) + axes.z_axis.label = z_label + for axis in axes: + axis.add(axis.label) + return axes + +#----------------------------------------------------------- + +class VectorField3D(VGroup): + CONFIG = { + "delta_x": 1, + "delta_y": 1, + "delta_z": 1, + "x_min": int(np.floor(-FRAME_WIDTH / 2)), + "x_max": int(np.ceil(FRAME_WIDTH / 2)), + "y_min": int(np.floor(-FRAME_HEIGHT / 2)), + "y_max": int(np.ceil(FRAME_HEIGHT / 2)), + "z_min":-1, + "z_max": 1, + "min_magnitude": 0, + "max_magnitude": 4, + "colors": DEFAULT_SCALAR_FIELD_COLORS, + # Takes in actual norm, spits out displayed norm + "length_func": lambda norm: 0.45 * sigmoid(norm), + "opacity": 1.0, + "vector_config": {}, + } + '''Position of the tip of vector to be fixed''' + def __init__(self, func, **kwargs): + VGroup.__init__(self, **kwargs) + self.func = func + self.rgb_gradient_function = get_rgb_gradient_function( + self.min_magnitude, + self.max_magnitude, + self.colors, + flip_alphas=False + ) + x_range = np.arange( + self.x_min, + self.x_max + self.delta_x, + self.delta_x + ) + y_range = np.arange( + self.y_min, + self.y_max + self.delta_y, + self.delta_y + ) + z_range = np.arange( + self.z_min, + self.z_max + self.delta_z, + self.delta_z + ) + for x, y, z in it.product(x_range, y_range, z_range): + point = x * RIGHT + y * UP + z * OUT + # print(point) + self.add(self.get_vector(point)) + self.set_opacity(self.opacity) + + def get_vector(self, point, **kwargs): + output = np.array(self.func(point)) + norm = get_norm(output) + if norm == 0: + output *= 0 + else: + output *= self.length_func(norm) / norm + # norm=np.linalg.norm(output) + vector_config = dict(self.vector_config) + vector_config.update(kwargs) + + vect = Vector( + output, + **vector_config + ) + vect_perp=vect.copy().rotate(PI/2, axis=output) + vect= VGroup(vect,vect_perp) + # vect= self.position_vector(vect,point,output,norm) + vect.shift(point) + fill_color = rgb_to_color( + self.rgb_gradient_function(np.array([norm]))[0] + ) + vect.set_color(fill_color) + return vect + + '''def position_vector(self,vect,point,output,norm): + theta,phi=self.get_theta_phi(output,norm) + vect.rotate(PI-phi, axis=RIGHT) + vect.rotate(theta, axis=IN) + # or apply rotation matrix? + return vect + + def get_theta_phi(self,output,norm): + if norm==0: + phi,theta=0,0 + else: + phi= np.arccos(output[-1]/norm) + if output[0]!=0: + theta= np.arccos(output[0]/(norm*np.sin(phi))) + else: + theta= 0 + return phi,theta''' + + + + #uploaded by Somnath Pandit. FSF2020_Vector_fields + + + |