Some refactor of NumberPlane. Quite likely breaks some old_projects

This commit is contained in:
Grant Sanderson
2017-05-23 13:17:31 -07:00
parent ea3535b0d6
commit c5e18f4eef
9 changed files with 100 additions and 107 deletions

View File

@ -1349,7 +1349,7 @@ class IntroduceProductAsArea(ReconfigurableScene):
line = NumberLine(
x_min = 0,
x_max = self.slider_x_max,
space_unit_to_num = float(self.slider_width)/self.slider_x_max,
unit_size = float(self.slider_width)/self.slider_x_max,
color = GREY,
numbers_with_elongated_ticks = numbers,
tick_frequency = 0.25,

View File

@ -1982,7 +1982,7 @@ class ASecondIntegralSensation(TeacherStudentsScene):
continuum = UnitInterval(
color = GREY,
space_unit_to_num = 6
unit_size = 6
)
continuum.next_to(finite_average, RIGHT, 2)
line = Line(continuum.get_left(), continuum.get_right())

View File

@ -1415,7 +1415,7 @@ class DerivativeAsTangentLine(ZoomedScene):
x_axis = NumberLine(
x_min = -0.25,
x_max = 4,
space_unit_to_num = 2,
unit_size = 2,
tick_frequency = 0.25,
leftmost_tick = -0.25,
numbers_with_elongated_ticks = [0, 1, 2, 3, 4],
@ -1431,7 +1431,7 @@ class DerivativeAsTangentLine(ZoomedScene):
y_axis = NumberLine(
x_min = -2,
x_max = 20,
space_unit_to_num = 0.3,
unit_size = 0.3,
tick_frequency = 2.5,
leftmost_tick = 0,
longer_tick_multiple = -2,

View File

@ -2217,7 +2217,7 @@ class FactorizationPattern(Scene):
line = NumberLine(
x_min = 0,
x_max = 36,
space_unit_to_num = 0.4,
unit_size = 0.4,
numbers_to_show = range(0, 33, 4),
numbers_with_elongated_ticks = range(0, 33, 4),
)

View File

@ -44,7 +44,7 @@ class TrigRepresentationsScene(Scene):
def init_axes(self):
self.axes = Axes(
space_unit_to_num = self.unit_length,
unit_size = self.unit_length,
)
self.axes.highlight(self.axes_color)
self.add(self.axes)

View File

@ -461,7 +461,7 @@ class DefineForRealS(PiCreatureScene):
x_max = 3,
tick_frequency = 0.25,
numbers_with_elongated_ticks = range(4),
space_unit_to_num = 3,
unit_size = 3,
)
number_line.add_numbers()
number_line.next_to(self.pi_creature, LEFT)
@ -862,7 +862,7 @@ class FromRealToComplex(ComplexTransformationScene):
def show_real_to_real(self):
zeta = self.get_zeta_definition("2", "\\frac{\\pi^2}{6}")
number_line = NumberLine(
space_unit_to_num = 2,
unit_size = 2,
tick_frequency = 0.5,
numbers_with_elongated_ticks = range(-2, 3)
)

View File

@ -13,16 +13,8 @@ from scene import Scene
class ComplexTransformationScene(Scene):
CONFIG = {
"plane_config" : {
"x_line_frequency" : 1,
"y_line_frequency" : 1,
"secondary_line_ratio" : 1,
},
"plane_config" : {},
"background_fade_factor" : 0.5,
"x_min" : -int(SPACE_WIDTH),
"x_max" : int(SPACE_WIDTH),
"y_min" : -SPACE_HEIGHT,
"y_max" : SPACE_HEIGHT,
"use_multicolored_plane" : False,
"vert_start_color" : BLUE, ##TODO
"vert_end_color" : BLUE,
@ -34,11 +26,14 @@ class ComplexTransformationScene(Scene):
"run_time" : 5,
},
"background_label_scale_val" : 0.5,
"include_coordinate_labels" : True,
}
def setup(self):
self.foreground_mobjects = []
self.transformable_mobjects = []
self.add_background_plane()
if self.include_coordinate_labels:
self.add_coordinate_labels()
def add_foreground_mobject(self, mobject):
self.add_foreground_mobjects(mobject)
@ -62,49 +57,38 @@ class ComplexTransformationScene(Scene):
)
def add_background_plane(self):
background = NumberPlane(**self.plane_config).fade(
self.background_fade_factor
)
real_labels = VGroup(*[
TexMobject(str(x)).shift(
background.num_pair_to_point((x, 0))
)
for x in range(-int(background.x_radius), int(background.x_radius))
])
imag_labels = VGroup(*[
TexMobject("%di"%y).shift(
background.num_pair_to_point((0, y))
)
for y in range(-int(background.y_radius), int(background.y_radius))
if y != 0
])
for labels in real_labels, imag_labels:
for label in labels:
label.scale_in_place(self.background_label_scale_val)
label.next_to(label.get_center(), DOWN+LEFT, buff = SMALL_BUFF)
label.add_background_rectangle()
background.add(labels)
self.real_labels = real_labels
self.imag_labels = imag_labels
background = ComplexPlane(**self.plane_config)
background.fade(self.background_fade_factor)
self.add(background)
self.background = background
def add_transformable_plane(self, animate = False):
self.plane_config.update({
"x_radius" : (self.x_max - self.x_min)/2.,
"y_radius" : (self.y_max - self.y_min)/2.,
})
plane = NumberPlane(**self.plane_config)
plane.shift(
(self.x_max+self.x_min)*RIGHT/2.,
(self.y_max+self.y_min)*UP/2.,
)
def add_coordinate_labels(self):
self.background.add_coordinates()
self.add(self.background)
def add_transformable_plane(self, **kwargs):
self.plane = self.get_transformable_plane()
self.add(self.plane)
def get_transformable_plane(self, x_range = None, y_range = None):
"""
x_range and y_range would be tuples (min, max)
"""
plane_config = dict(self.plane_config)
shift_val = ORIGIN
if x_range is not None:
x_min, x_max = x_range
plane_config["x_radius"] = x_max - x_min
shift_val += (x_max+x_min)*RIGHT/2.
if y_range is not None:
y_min, y_max = y_range
plane_config["y_radius"] = y_max - y_min
shift_val += (y_max+y_min)*UP/2.
plane = ComplexPlane(**plane_config)
plane.shift(shift_val)
if self.use_multicolored_plane:
self.paint_plane(plane)
if animate:
self.play(ShowCreation(plane, run_time = 2))
else:
self.add(plane)
self.plane = plane
return plane
def prepare_for_transformation(self, mob):
if hasattr(mob, "prepare_for_nonlinear_transform"):
@ -114,7 +98,6 @@ class ComplexTransformationScene(Scene):
#TODO...
def paint_plane(self, plane):
if self.use_multicolored_plane:
for lines in plane.main_lines, plane.secondary_lines:
lines.gradient_highlight(
self.vert_start_color,
@ -122,14 +105,13 @@ class ComplexTransformationScene(Scene):
self.horiz_start_color,
self.horiz_end_color,
)
plane.axes.gradient_highlight(
self.horiz_start_color,
self.vert_start_color
)
# plane.axes.gradient_highlight(
# self.horiz_start_color,
# self.vert_start_color
# )
def z_to_point(self, z):
z = complex(z)
return self.background.num_pair_to_point((z.real, z.imag))
return self.background.number_to_point(z)
def get_transformer(self, **kwargs):
transform_kwargs = dict(self.default_apply_complex_function_kwargs)
@ -145,7 +127,14 @@ class ComplexTransformationScene(Scene):
def apply_complex_function(self, func, added_anims = [], **kwargs):
transformer, transform_kwargs = self.get_transformer(**kwargs)
transformer.generate_target()
#Rescale, apply function, scale back
transformer.target.shift(-self.background.get_center_point())
transformer.target.scale(1./self.background.unit_size)
transformer.target.apply_complex_function(func)
transformer.target.scale(self.background.unit_size)
transformer.target.shift(self.background.get_center_point())
#
for mob in transformer.target[0].family_members_with_points():
mob.make_smooth()
if self.post_transformation_stroke_width is not None:
@ -159,7 +148,8 @@ class ComplexTransformationScene(Scene):
transformer, transform_kwargs = self.get_transformer(**kwargs)
def homotopy(x, y, z, t):
output = complex_homotopy(complex(x, y), t)
return (output.real, output.imag, z)
rescaled_output = self.z_to_point(output)
return (rescaled_output.real, rescaled_output.imag, z)
self.play(
SmoothedVectorizedHomotopy(
@ -177,23 +167,20 @@ def complex_string(complex_num):
class ComplexPlane(NumberPlane):
CONFIG = {
"color" : BLUE,
"unit_to_spatial_width" : 1,
"unit_size" : 1,
"line_frequency" : 1,
"faded_line_frequency" : 0.5,
"number_at_center" : complex(0),
"number_scale_factor" : 0.5,
}
def __init__(self, **kwargs):
digest_config(self, kwargs)
kwargs.update({
"x_unit_to_spatial_width" : self.unit_to_spatial_width,
"y_unit_to_spatial_height" : self.unit_to_spatial_width,
"x_unit_size" : self.unit_size,
"y_unit_size" : self.unit_size,
"x_line_frequency" : self.line_frequency,
"x_faded_line_frequency" : self.faded_line_frequency,
"y_line_frequency" : self.line_frequency,
"y_faded_line_frequency" : self.faded_line_frequency,
"num_pair_at_center" : (self.number_at_center.real,
self.number_at_center.imag),
})
NumberPlane.__init__(self, **kwargs)

View File

@ -50,7 +50,7 @@ class GraphScene(Scene):
x_axis = NumberLine(
x_min = self.x_min,
x_max = self.x_max,
space_unit_to_num = self.space_unit_to_x,
unit_size = self.space_unit_to_x,
tick_frequency = self.x_tick_frequency,
leftmost_tick = self.x_leftmost_tick,
numbers_with_elongated_ticks = self.x_labeled_nums,
@ -81,7 +81,7 @@ class GraphScene(Scene):
y_axis = NumberLine(
x_min = self.y_min,
x_max = self.y_max,
space_unit_to_num = self.space_unit_to_y,
unit_size = self.space_unit_to_y,
tick_frequency = self.y_tick_frequency,
leftmost_tick = self.y_bottom_tick,
numbers_with_elongated_ticks = self.y_labeled_nums,

View File

@ -11,7 +11,7 @@ class NumberLine(VMobject):
"color" : BLUE,
"x_min" : -SPACE_WIDTH,
"x_max" : SPACE_WIDTH,
"space_unit_to_num" : 1,
"unit_size" : 1,
"tick_size" : 0.1,
"tick_frequency" : 1,
"leftmost_tick" : None, #Defaults to ceil(x_min)
@ -35,7 +35,7 @@ class NumberLine(VMobject):
self.add_tick(x, self.tick_size)
for x in self.numbers_with_elongated_ticks:
self.add_tick(x, self.longer_tick_multiple*self.tick_size)
self.stretch(self.space_unit_to_num, 0)
self.stretch(self.unit_size, 0)
self.shift(-self.number_to_point(self.number_at_center))
def add_tick(self, x, size):
@ -108,7 +108,7 @@ class UnitInterval(NumberLine):
CONFIG = {
"x_min" : 0,
"x_max" : 1,
"space_unit_to_num" : 6,
"unit_size" : 6,
"tick_frequency" : 0.1,
"numbers_with_elongated_ticks" : [0, 1],
"number_at_center" : 0.5,
@ -130,20 +130,26 @@ class NumberPlane(VMobject):
"secondary_color" : BLUE_E,
"axes_color" : WHITE,
"secondary_stroke_width" : 1,
"x_radius": SPACE_WIDTH,
"y_radius": SPACE_HEIGHT,
"space_unit_to_x_unit" : 1,
"space_unit_to_y_unit" : 1,
"x_radius": None,
"y_radius": None,
"x_unit_size" : 1,
"y_unit_size" : 1,
"center_point" : ORIGIN,
"x_line_frequency" : 1,
"y_line_frequency" : 1,
"secondary_line_ratio" : 1,
"written_coordinate_height" : 0.2,
"written_coordinate_nudge" : 0.1*(DOWN+RIGHT),
"coords_at_center" : (0, 0),
"propogate_style_to_family" : False,
}
def generate_points(self):
if self.x_radius is None:
center_to_edge = (SPACE_WIDTH + abs(self.center_point[0]))
self.x_radius = center_to_edge / self.x_unit_size
if self.y_radius is None:
center_to_edge = (SPACE_HEIGHT + abs(self.center_point[1]))
self.y_radius = center_to_edge / self.y_unit_size
self.axes = VMobject()
self.main_lines = VMobject()
self.secondary_lines = VMobject()
@ -176,8 +182,9 @@ class NumberPlane(VMobject):
else:
self.secondary_lines.add(line1, line2)
self.add(self.secondary_lines, self.main_lines, self.axes)
self.stretch(self.space_unit_to_x_unit, 0)
self.stretch(self.space_unit_to_y_unit, 1)
self.stretch(self.x_unit_size, 0)
self.stretch(self.y_unit_size, 1)
self.shift(self.center_point)
#Put x_axis before y_axis
y_axis, x_axis = self.axes.split()
self.axes = VMobject(x_axis, y_axis)
@ -192,26 +199,25 @@ class NumberPlane(VMobject):
return self
def get_center_point(self):
return self.num_pair_to_point(self.coords_at_center)
return self.coords_to_point(0, 0)
def coords_to_point(self, x, y):
x, y = np.array([x, y]) + self.coords_at_center
x, y = np.array([x, y])
result = self.axes.get_center()
result += x*self.get_space_unit_to_x_unit()*RIGHT
result += y*self.get_space_unit_to_y_unit()*UP
result += x*self.get_x_unit_size()*RIGHT
result += y*self.get_y_unit_size()*UP
return result
def point_to_coords(self, point):
new_point = point - self.axes.get_center()
center_x, center_y = self.coords_at_center
x = center_x + new_point[0]/self.get_space_unit_to_x_unit()
y = center_y + new_point[1]/self.get_space_unit_to_y_unit()
x = new_point[0]/self.get_x_unit_size()
y = new_point[1]/self.get_y_unit_size()
return x, y
def get_space_unit_to_x_unit(self):
def get_x_unit_size(self):
return self.axes.get_width() / (2.0*self.x_radius)
def get_space_unit_to_y_unit(self):
def get_y_unit_size(self):
return self.axes.get_height() / (2.0*self.y_radius)
def get_coordinate_labels(self, x_vals = None, y_vals = None):
@ -225,7 +231,7 @@ class NumberPlane(VMobject):
if val == 0:
continue
num_pair[index] = val
point = self.num_pair_to_point(num_pair)
point = self.coords_to_point(*num_pair)
num = TexMobject(str(val))
num.add_background_rectangle()
num.scale_to_fit_height(