mirror of
https://github.com/3b1b/manim.git
synced 2025-08-02 11:03:03 +08:00
Merge branch 'master' into lighthouse
This commit is contained in:
@ -2455,18 +2455,57 @@ class WhiteComplexExponentialExpression(DrawFrequencyPlot):
|
||||
self.generate_center_of_mass_dot_update_anim()
|
||||
|
||||
self.add(graph, pol_graph, wps_label)
|
||||
self.set_variables_as_attrs(pol_graph, wps_label)
|
||||
self.time_axes_group = VGroup(self.time_axes, graph)
|
||||
|
||||
def show_winding_with_both_coordinates(self):
|
||||
#TODO, tie dashed lines to dot
|
||||
com_dot = self.center_of_mass_dot
|
||||
plane = self.circle_plane
|
||||
v_line = Line(ORIGIN, UP)
|
||||
h_line = Line(ORIGIN, RIGHT)
|
||||
lines = VGroup(v_line, h_line)
|
||||
lines.highlight(PINK)
|
||||
def lines_update(lines):
|
||||
point = com_dot.get_center()
|
||||
x, y = plane.point_to_coords(point)
|
||||
h_line.put_start_and_end_on(
|
||||
plane.coords_to_point(0, y), point
|
||||
)
|
||||
v_line.put_start_and_end_on(
|
||||
plane.coords_to_point(x, 0), point
|
||||
)
|
||||
lines_update_anim = UpdateFromFunc(lines, lines_update)
|
||||
lines_update_anim.update(0)
|
||||
self.add(lines)
|
||||
|
||||
self.change_frequency(
|
||||
2.0, run_time = 15,
|
||||
2.04,
|
||||
added_anims = [
|
||||
lines_update_anim,
|
||||
self.center_of_mass_dot_anim,
|
||||
],
|
||||
run_time = 15,
|
||||
rate_func = bezier([0, 0, 1, 1])
|
||||
)
|
||||
self.wait()
|
||||
|
||||
self.dot_component_anim = lines_update_anim
|
||||
|
||||
def show_plane_as_complex_plane(self):
|
||||
pass
|
||||
to_fade = VGroup(
|
||||
self.time_axes_group, self.pol_graph, self.wps_label
|
||||
)
|
||||
plane = self.circle_plane
|
||||
complex_plane_title = TextMobject("Complex plane")
|
||||
complex_plane_title.add_background_rectangle()
|
||||
complex_plane_title.to_edge(UP)
|
||||
coordinate_labels = plane.get_coordinate_labels()
|
||||
|
||||
self.play(FadeOut(to_fade))
|
||||
self.play(Write(complex_plane_title))
|
||||
self.play(Write(coordinate_labels))
|
||||
self.wait()
|
||||
|
||||
|
||||
def show_eulers_formula(self):
|
||||
pass
|
||||
|
33
helpers.py
33
helpers.py
@ -252,14 +252,14 @@ def get_all_descendent_classes(Class):
|
||||
result.append(Child)
|
||||
return result
|
||||
|
||||
def filtered_locals(local_args):
|
||||
result = local_args.copy()
|
||||
def filtered_locals(caller_locals):
|
||||
result = caller_locals.copy()
|
||||
ignored_local_args = ["self", "kwargs"]
|
||||
for arg in ignored_local_args:
|
||||
result.pop(arg, local_args)
|
||||
result.pop(arg, caller_locals)
|
||||
return result
|
||||
|
||||
def digest_config(obj, kwargs, local_args = {}):
|
||||
def digest_config(obj, kwargs, caller_locals = {}):
|
||||
"""
|
||||
Sets init args and CONFIG values as local variables
|
||||
|
||||
@ -268,19 +268,25 @@ def digest_config(obj, kwargs, local_args = {}):
|
||||
be easily passed into instantiation, and is attached
|
||||
as an attribute of the object.
|
||||
"""
|
||||
### Assemble list of CONFIGs from all super classes
|
||||
|
||||
# Assemble list of CONFIGs from all super classes
|
||||
classes_in_hierarchy = [obj.__class__]
|
||||
configs = []
|
||||
static_configs = []
|
||||
while len(classes_in_hierarchy) > 0:
|
||||
Class = classes_in_hierarchy.pop()
|
||||
classes_in_hierarchy += Class.__bases__
|
||||
if hasattr(Class, "CONFIG"):
|
||||
configs.append(Class.CONFIG)
|
||||
static_configs.append(Class.CONFIG)
|
||||
|
||||
#Order matters a lot here, first dicts have higher priority
|
||||
all_dicts = [kwargs, filtered_locals(local_args), obj.__dict__]
|
||||
all_dicts += configs
|
||||
caller_locals = filtered_locals(caller_locals)
|
||||
all_dicts = [kwargs, caller_locals, obj.__dict__]
|
||||
all_dicts += static_configs
|
||||
all_new_dicts = [kwargs, caller_locals] + static_configs
|
||||
obj.__dict__ = merge_config(all_dicts)
|
||||
#Keep track of the configuration of objects upon
|
||||
#instantiation
|
||||
obj.initial_config = merge_config(all_new_dicts)
|
||||
|
||||
def merge_config(all_dicts):
|
||||
all_config = reduce(op.add, [d.items() for d in all_dicts])
|
||||
@ -295,6 +301,15 @@ def merge_config(all_dicts):
|
||||
config[key] = merge_config([config[key], value])
|
||||
return config
|
||||
|
||||
def soft_dict_update(d1, d2):
|
||||
"""
|
||||
Adds key values pairs of d2 to d1 only when d1 doesn't
|
||||
already have that key
|
||||
"""
|
||||
for key, value in d2.items():
|
||||
if key not in d1:
|
||||
d1[key] = value
|
||||
|
||||
def digest_locals(obj, keys = None):
|
||||
caller_locals = filtered_locals(
|
||||
inspect.currentframe().f_back.f_locals
|
||||
|
@ -85,15 +85,17 @@ class VMobject(Mobject):
|
||||
return self
|
||||
|
||||
def match_style(self, vmobject):
|
||||
#TODO: Should this be smart about matching the
|
||||
#style of the family members, if they happen to
|
||||
#be different?
|
||||
self.set_style_data(
|
||||
stroke_color = vmobject.get_stroke_color(),
|
||||
stroke_width = vmobject.get_stroke_width(),
|
||||
fill_color = vmobject.get_fill_color(),
|
||||
fill_opacity = vmobject.get_fill_opacity(),
|
||||
family = False
|
||||
)
|
||||
#TODO: This behaviro may not be optimal when submobject
|
||||
#lists dont' have the same length
|
||||
for sm1, sm2 in zip(self.submobjects, vmobject.submobjects):
|
||||
sm1.match_style(sm2)
|
||||
return
|
||||
|
||||
def fade(self, darkness = 0.5):
|
||||
|
@ -11,7 +11,7 @@ class DecimalNumber(VMobject):
|
||||
"num_decimal_points" : 2,
|
||||
"digit_to_digit_buff" : 0.05,
|
||||
"show_ellipsis" : False,
|
||||
"unit" : None
|
||||
"unit" : None,
|
||||
}
|
||||
def __init__(self, number, **kwargs):
|
||||
digest_config(self, kwargs, locals())
|
||||
@ -27,7 +27,9 @@ class DecimalNumber(VMobject):
|
||||
if self.show_ellipsis:
|
||||
self.add(TexMobject("\\dots"))
|
||||
|
||||
|
||||
if self.unit is not None:
|
||||
self.add(TexMobject(self.unit))
|
||||
|
||||
self.arrange_submobjects(
|
||||
buff = self.digit_to_digit_buff,
|
||||
aligned_edge = DOWN
|
||||
@ -39,20 +41,8 @@ class DecimalNumber(VMobject):
|
||||
self.submobjects[1], LEFT,
|
||||
buff = self.digit_to_digit_buff
|
||||
)
|
||||
|
||||
|
||||
if self.unit != None:
|
||||
unit_sign = TexMobject(self.unit)
|
||||
unit_sign.next_to(self.submobjects[-1],RIGHT,
|
||||
buff = self.digit_to_digit_buff)
|
||||
|
||||
if self.unit == "^\\circ":
|
||||
unit_sign.align_to(self,UP)
|
||||
else:
|
||||
unit_sign.align_to(self,DOWN)
|
||||
self.add(unit_sign)
|
||||
|
||||
|
||||
if self.unit == "\\circ":
|
||||
self[-1].align_to(self, UP)
|
||||
|
||||
class Integer(VGroup):
|
||||
CONFIG = {
|
||||
@ -72,20 +62,18 @@ class ChangingDecimal(Animation):
|
||||
CONFIG = {
|
||||
"num_decimal_points" : None,
|
||||
"show_ellipsis" : None,
|
||||
"spare_parts" : 2,
|
||||
"position_update_func" : None,
|
||||
"tracked_mobject" : None
|
||||
}
|
||||
def __init__(self, decimal_number_mobject, number_update_func, **kwargs):
|
||||
digest_config(self, kwargs, locals())
|
||||
if self.num_decimal_points is None:
|
||||
self.num_decimal_points = decimal_number_mobject.num_decimal_points
|
||||
if self.show_ellipsis is None:
|
||||
self.show_ellipsis = decimal_number_mobject.show_ellipsis
|
||||
decimal_number_mobject.add(*[
|
||||
VectorizedPoint(decimal_number_mobject.get_corner(DOWN+LEFT))
|
||||
for x in range(self.spare_parts)]
|
||||
self.decimal_number_config = dict(
|
||||
decimal_number_mobject.initial_config
|
||||
)
|
||||
for attr in "num_decimal_points", "show_ellipsis":
|
||||
value = getattr(self, attr)
|
||||
if value is not None:
|
||||
self.decimal_number_config[attr] = value
|
||||
if self.tracked_mobject:
|
||||
dmc = decimal_number_mobject.get_center()
|
||||
tmc = self.tracked_mobject.get_center()
|
||||
@ -100,13 +88,11 @@ class ChangingDecimal(Animation):
|
||||
decimal = self.decimal_number_mobject
|
||||
new_number = self.number_update_func(alpha)
|
||||
new_decimal = DecimalNumber(
|
||||
new_number,
|
||||
num_decimal_points = self.num_decimal_points,
|
||||
show_ellipsis = self.show_ellipsis,
|
||||
unit = self.decimal_number_mobject.unit
|
||||
new_number, **self.decimal_number_config
|
||||
)
|
||||
new_decimal.replace(decimal, dim_to_match = 1)
|
||||
new_decimal.highlight(decimal.get_color())
|
||||
new_decimal.match_height(decimal)
|
||||
new_decimal.move_to(decimal)
|
||||
new_decimal.match_style(decimal)
|
||||
|
||||
decimal.submobjects = new_decimal.submobjects
|
||||
decimal.number = new_number
|
||||
|
Reference in New Issue
Block a user