More moser, count method of scene implemented

This commit is contained in:
Grant Sanderson
2015-04-16 21:09:12 -07:00
parent d79db9d142
commit 5aff0b6374
6 changed files with 149 additions and 31 deletions

View File

@ -14,7 +14,7 @@ from constants import *
from mobject import Mobject
class Animation(object):
def __init__(self,
def __init__(self,
mobject,
run_time = DEFAULT_ANIMATION_RUN_TIME,
alpha_func = high_inflection_0_to_1,
@ -217,6 +217,18 @@ class Transform(Animation):
)[self.non_redundant_m2_indices]
)
class FadeToColor(Transform):
def __init__(self, mobject, color, *args, **kwargs):
target = copy.deepcopy(mobject).highlight(color)
Transform.__init__(self, mobject, target, *args, **kwargs)
class ScaleInPlace(Transform):
def __init__(self, mobject, scale_factor, *args, **kwargs):
target = copy.deepcopy(mobject)
center = mobject.get_center()
target.shift(-center).scale(scale_factor).shift(center)
Transform.__init__(self, mobject, target, *args, **kwargs)
class ApplyMethod(Transform):
def __init__(self, method, mobject, *args, **kwargs):
"""
@ -232,7 +244,7 @@ class ApplyMethod(Transform):
mobject,
method(copy.deepcopy(mobject), *method_args),
*args, **kwargs
)
)
class ApplyFunction(Transform):
def __init__(self, function, mobject, run_time = DEFAULT_ANIMATION_RUN_TIME,

View File

@ -130,6 +130,7 @@ class Mobject(object):
"""
Condition is function which takes in one arguments, (x, y, z).
"""
#TODO, Should self.color change?
to_change = np.apply_along_axis(condition, 1, self.points)
self.rgbs[to_change, :] *= 0
self.rgbs[to_change, :] += Color(color).get_rgb()

0
moser/__init__.py Normal file
View File

View File

@ -36,10 +36,17 @@ class CircleScene(Scene):
##################################################
def count_lines(*radians):
#TODO, Count things explicitly?
sc = CircleScene(radians)
text = tex_mobject(r"\text{How Many Lines?}", size = r"\large")
text_center = (sc.radius + 1, sc.radius -1, 0)
text.scale(0.4).shift(text_center)
scale_factor = 0.4
text = tex_mobject(r"\text{How Many Lines?}", size = r"\large")
n = len(radians)
formula, answer = tex_mobject([
r"{%d \choose 2} = \frac{%d(%d - 1)}{2} = "%(n, n, n),
str(choose(n, 2))
])
text.scale(scale_factor).shift(text_center)
x = text_center[0]
new_lines = [
Line((x-1, y, 0), (x+1, y, 0))
@ -55,6 +62,16 @@ def count_lines(*radians):
Transform(line1, line2, run_time = 2)
for line1, line2 in zip(sc.lines, new_lines)
])
sc.dither()
sc.remove(text)
sc.count(new_lines)
anims = [FadeIn(formula)]
for mob in sc.mobjects:
if mob == sc.number: #put in during animate_count
anims.append(Transform(mob, answer))
else:
anims.append(FadeOut(mob))
sc.animate(*anims, run_time = 1)
return sc
@ -63,35 +80,44 @@ def count_intersection_points(*radians):
radians.sort()
sc = CircleScene(radians)
intersection_points = [
intersection([p[0], p[2]], [p[1], p[3]])
intersection((p[0], p[2]), (p[1], p[3]))
for p in it.combinations(sc.points, 4)
]
intersection_dots = CompoundMobject(*[
Dot(point) for point in intersection_points
])
how_many = tex_mobject(r"""
\text{How many}\\
\text{intersection points?}
""", size = r"\large")
text_center = (sc.radius + 1, sc.radius -1, 0)
how_many.scale(0.4).shift(text_center)
new_points = [
(text_center[0], y, 0)
for y in np.arange(
-(sc.radius - 1),
sc.radius - 1,
(2*sc.radius - 2)/choose(len(sc.points), 4)
)
]
new_dots = CompoundMobject(*[
Dot(point) for point in new_points
intersection_dots = [Dot(point) for point in intersection_points]
text_center = (sc.radius + 1, sc.radius -0.5, 0)
size = r"\large"
scale_factor = 0.4
text = tex_mobject(r"\text{How Many Intersection Points?}", size = size)
n = len(radians)
formula, answer = tex_mobjects([
r"{%d \choose 4} = \frac{%d(%d - 1)(%d - 2)(%d-3)}{1\cdot 2\cdot 3 \cdot 4}="%(n, n, n, n, n),
str(choose(n, 4))
])
text.scale(scale_factor).shift(text_center)
# new_points = [
# (text_center[0], y, 0)
# for y in np.arange(
# -(sc.radius - 1),
# sc.radius - 1,
# (2*sc.radius - 2)/choose(len(sc.points), 4)
# )
# ]
# new_dots = CompoundMobject(*[
# Dot(point) for point in new_points
# ])
sc.add(how_many)
sc.animate(ShowCreation(intersection_dots))
sc.add(intersection_dots)
sc.animate(Transform(intersection_dots, new_dots))
sc.add(tex_mobject(str(len(new_points))).center())
sc.add(text)
sc.count(intersection_dots, "show_creation", num_offset = (0, 0, 0))
sc.dither()
# sc.animate(Transform(intersection_dots, new_dots))
anims = []
for mob in sc.mobjects:
if mob == sc.number: #put in during animate_count
anims.append(Transform(mob, answer))
else:
anims.append(FadeOut(mob))
anims.append(FadeIn(formula)) #Put here to so they are foreground
sc.animate(*anims, run_time = 1)
return sc
def non_general_position():
@ -127,11 +153,52 @@ def non_general_position():
])
return sc1
def line_corresponds_with_pair(radians, r1, r2):
sc = CircleScene(radians)
#Remove from sc.lines list, so they won't be faded out
assert r1 in radians and r2 in radians
line_index = list(it.combinations(radians, 2)).index((r1, r2))
radians = list(radians)
dot0_index, dot1_index = radians.index(r1), radians.index(r2)
line, dot0, dot1 = sc.lines[line_index], sc.dots[dot0_index], sc.dots[dot1_index]
sc.lines.remove(line)
sc.dots.remove(dot0)
sc.dots.remove(dot1)
sc.dither()
sc.animate(*[FadeOut(mob) for mob in sc.lines + sc.dots])
sc.add(sc.circle)
sc.animate(*[
ScaleInPlace(mob, 3, alpha_func = there_and_back)
for mob in (dot0, dot1)
])
sc.animate(Transform(line, dot0))
return sc
def illustrate_n_choose_2(n):
#TODO, maybe make this snazzy
sc = Scene()
nrange = range(1, n+1)
nrange_im = tex_mobject(str(nrange))
pairs_str = str(list(it.combinations(nrange, 2)))
exp = tex_mobject(r"{{%d \choose 2} = %d \text{ total pairs}}"%(n, choose(n, 2)))
pairs_im = tex_mobject(r"\underbrace{%s}"%pairs_str, size=r"\tiny")
nrange_im.shift((0, 2, 0))
pairs_im.scale(0.7)
exp.shift((0, -2, 0))
sc.add(nrange_im)
sc.dither()
sc.animate(FadeIn(pairs_im), FadeIn(exp))
sc.add(pairs_im)
return sc
##################################################
if __name__ == '__main__':
radians = np.arange(0, 6, 6.0/7)
count_lines(*radians).write_to_movie("moser/CountLines")
# count_lines(*radians).write_to_movie("moser/CountLines")
count_intersection_points(*radians).write_to_movie("moser/CountIntersectionPoints")
non_general_position().write_to_movie("moser/NonGeneralPosition")
# non_general_position().write_to_movie("moser/NonGeneralPosition")
# line_corresponds_with_pair(radians, radians[3], radians[4]).write_to_movie("moser/LineCorrespondsWithPair34")
# line_corresponds_with_pair(radians, radians[2], radians[5]).write_to_movie("moser/LineCorrespondsWithPair25")
# illustrate_n_choose_2(6).write_to_movie("moser/IllustrateNChoose2with6")

View File

@ -2,6 +2,9 @@ import numpy as np
import operator as op
import itertools as it
from constants import *
from image_mobject import *
def choose(n, r):
if n < r: return 0
if r == 0: return 1
@ -32,3 +35,6 @@ def intersection(line1, line2):
result = np.dot(transform, [[x_intercept], [0]])
result = result.reshape((2,)) + p0
return result

View File

@ -12,6 +12,7 @@ import inspect
from helpers import *
from mobject import *
from image_mobject import *
from animation import *
import displayer as disp
@ -98,6 +99,37 @@ class Scene(object):
self.add(*moving_mobjects)
progress_bar.finish()
def count(self, mobjects, mode = "highlight",
color = "red",
num_offset = (SPACE_WIDTH - 1, SPACE_HEIGHT - 1, 0),
run_time = 5.0):
"""
Note: Leaves scene with a "number" attribute
for the final number mobject
"""
if len(mobjects) > 50: #TODO
raise Exception("I don't know if you should be counting \
too many mobjects...")
if mode not in ["highlight", "show_creation"]:
raise Exception("Invalid mode")
frame_time = run_time / len(mobjects)
if mode == "highlight":
self.add(*mobjects)
for mob, num in zip(mobjects, it.count(1)):
num_mob = tex_mobject(str(num))
num_mob.center().shift(num_offset)
self.add(num_mob)
if mode == "highlight":
original_color = mob.color
mob.highlight(color)
self.dither(frame_time)
mob.highlight(original_color)
if mode == "show_creation":
self.animate(ShowCreation(mob, run_time = frame_time))
self.remove(num_mob)
self.add(num_mob)
self.number = num_mob
def get_frame(self):
frame = self.background
for mob in self.mobjects: