From 0dee2b48260041c5bffe471af4160a7ab515a99b Mon Sep 17 00:00:00 2001 From: Somnath Pandit Date: Sat, 27 Jun 2020 14:40:33 +0530 Subject: slopefield --- .../vector-fields/file4_slope_field.py | 211 +++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 FSF-2020/calculus-of-several-variables/integrals-of-multivariable-functions/vector-fields/file4_slope_field.py (limited to 'FSF-2020/calculus-of-several-variables') diff --git a/FSF-2020/calculus-of-several-variables/integrals-of-multivariable-functions/vector-fields/file4_slope_field.py b/FSF-2020/calculus-of-several-variables/integrals-of-multivariable-functions/vector-fields/file4_slope_field.py new file mode 100644 index 0000000..853bf9e --- /dev/null +++ b/FSF-2020/calculus-of-several-variables/integrals-of-multivariable-functions/vector-fields/file4_slope_field.py @@ -0,0 +1,211 @@ +from manimlib.imports import * + + +class SlopeFields(GraphScene): + CONFIG = { + "x_min" : -2, + "x_max" : 2, + "y_min" : -2, + "y_max" : 2, + "graph_origin": ORIGIN+2.5*LEFT, + "x_axis_width": 7, + "y_axis_height": 7, + "x_tick_frequency": 1, + "y_tick_frequency": 1, + "default_slope_field_config": { + "delta_x": .25, + "delta_y": .25, + "min_magnitude": -PI, + "max_magnitude": PI, + "colors": [BLUE_B,GREEN_B,YELLOW,ORANGE], + "length_func": lambda norm : .6*sigmoid(norm), + "opacity": .75, + "slope_config": { + "stroke_width":6, + "max_stroke_width_to_length_ratio":6 + }, + }, + + "a":-3 ,"b": 3, "c": -3 ,"d": 3, + } + + 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) + + slope_field=self.get_slope_field( + lambda x,y:-2*(x-self.graph_origin[0])*(y-self.graph_origin[1]), + x_min=self.a-2.5, + x_max=self.b-2.5, + y_min=self.c, + y_max=self.d, + ) + self.add(slope_field) + '''self.show_points() + self.wait(.5) + self.show_func_machine() + self.wait(1) + self.produce_slopes(slope_field)''' + self.wait(2) + + + + + def show_points(self): + dn=1 + x_vals=np.arange(self.a,self.b,dn) + y_vals=np.arange(self.c,self.d,dn) + dots=VGroup() + for x_val in x_vals: + for y_val in y_vals: + dot=Dot( + self.coords_to_point(x_val,y_val), + radius=.05, + color=TEAL, + ) + dots.add(dot) + self.play(ShowCreation(dots, run_time=1)) + self.dots=dots + + def show_func_machine(self): + machine=RoundedRectangle( + height=3, + width=4, + color=PURPLE, + stroke_width=8 + ).to_edge(RIGHT, buff=.4) + + machine_label=TextMobject( + r"Line segment\\ with slope\\"," $y'=-2xy$", + stroke_width=1.2, + color=BLUE + ).next_to(machine,IN) + machine_label[1].set_color_by_gradient( + *self.default_slope_field_config["colors"] + ) + self.add(machine, machine_label) + + self.func_machine = machine + + + def produce_slopes(self,slope_field): + count,i=1,0 + self.run_time=1 + for dot in self.dots: + if i==count: + self.run_time=.05 + position=dot.get_center() + line= slope_field.get_slope(position) + self.go_to_machine(dot) + self.take_line_from_machine(line,position) + i+=1 + + def go_to_machine(self,dot): + if self.run_time>.5: + self.play(ApplyMethod( + dot.next_to, + self.func_machine,4*UP, + ), + run_time=self.run_time + ) + self.dot=dot + + def take_line_from_machine(self,vect,position): + vect.next_to(self.func_machine,DOWN,buff=.1) + if self.run_time>.5: + self.play( + ApplyMethod( + self.dot.shift,DOWN, + run_time=self.run_time + )), + self.play( + FadeOut(self.dot), + run_time=.2 + ) + self.play( + FadeIn(vect), + run_time=.4 + ) + else: + self.remove(self.dot) + self.add(vect) + self.wait(.1) + + self.play( + ApplyMethod( + vect.move_to,position + ), + run_time=self.run_time + ) + + def get_slope_field(self,func,**kwargs): + config = dict() + config.update(self.default_slope_field_config) + config.update(kwargs) + slope_field= SlopeField(func,**config) + + return slope_field + + +class SlopeField(VGroup): + CONFIG = { + "delta_x": 0.5, + "delta_y": 0.5, + "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)), + "min_magnitude": 0, + "max_magnitude": 2, + "slope_length_factor": .2, + "colors": DEFAULT_SCALAR_FIELD_COLORS, + "opacity": 1.0, + "line_config": {}, + } + + 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 + ) + for x, y in it.product(x_range, y_range): + point = x * RIGHT + y * UP + self.add(self.get_slope(point)) + self.set_opacity(self.opacity) + + def get_slope(self, point, **kwargs): + slope = self.func(*point[:2]) + line_config = dict(self.line_config) + line_config.update(kwargs) + line = Line(ORIGIN,self.slope_length_factor*RIGHT, **line_config) + line.move_to(point).rotate(np.arctan(slope)) + fill_color = rgb_to_color( + self.rgb_gradient_function(np.array([slope]))[0] + ) + line.set_color(fill_color) + return line + + + + +#uploaded by Somnath Pandit. FSF2020_Vector_fields + + + -- cgit