Merge branch 'lighthouse-grant' into lighthouse2

This commit is contained in:
Grant Sanderson 2018-03-05 20:11:45 -08:00
commit 3944c8a2d8
11 changed files with 4711 additions and 100 deletions

View file

@ -426,7 +426,6 @@ class IntroScene(PiCreatureScene):
self.ellipsis = TexMobject("\cdots")
self.ellipsis.scale(0.4)
for i in range(5, max_n1):
if i == 5:
@ -441,7 +440,6 @@ class IntroScene(PiCreatureScene):
GrowFromPoint(self.rects[i], self.euler_sum[10].get_center(),
run_time = 0.5)
)
for i in range(max_n1, max_n2):
self.play(
GrowFromPoint(self.rects[i], self.euler_sum[10].get_center(),
@ -929,15 +927,11 @@ class SingleLighthouseScene(PiCreatureScene):
class MorphIntoSunScene(PiCreatureScene):
def construct(self):
self.setup_elements()
self.morph_lighthouse_into_sun()
def setup_elements(self):
self.remove(self.get_primary_pi_creature())
SCREEN_SIZE = 3.0
@ -988,10 +982,8 @@ class MorphIntoSunScene(PiCreatureScene):
self.add_foreground_mobject(self.light_source.shadow)
self.add_foreground_mobject(morty)
self.light_source.dim_ambient
self.add(self.light_source.spotlight)
self.screen_tracker = ScreenTracker(self.light_source)
self.add(self.screen_tracker)
@ -4351,10 +4343,6 @@ class ArcHighlightOverlayScene(Scene):
)
flash_arcs(3)
class ThumbnailScene(Scene):
@ -4545,14 +4533,4 @@ class RightAnglesOverlay(Scene):
self.play(FadeOut(lines))
flash_arcs(3)

4651
active_projects/basel2.py Normal file

File diff suppressed because it is too large Load diff

View file

@ -101,9 +101,15 @@ class Swap(CyclicReplace):
pass #Renaming, more understandable for two entries
class GrowFromPoint(Transform):
CONFIG = {
"point_color" : None,
}
def __init__(self, mobject, point, **kwargs):
digest_config(self, kwargs)
target = mobject.copy()
point_mob = Point(point)
if self.point_color:
point_mob.highlight(self.point_color)
mobject.replace(point_mob)
mobject.highlight(point_mob.get_color())
Transform.__init__(self, mobject, target, **kwargs)

View file

@ -18,7 +18,6 @@ from camera import Camera
HELP_MESSAGE = """
Usage:
python extract_scene.py <module> [<scene name>]
-p preview in low quality
-s show and save picture of last frame
-w write result to file [this is default if nothing else is stated]
@ -35,7 +34,6 @@ SCENE_NOT_FOUND_MESSAGE = """
CHOOSE_NUMBER_MESSAGE = """
Choose number corresponding to desired scene/arguments.
(Use comma separated list for multiple entries)
Choice(s): """
INVALID_NUMBER_MESSAGE = "Fine then, if you don't want to give a valid number I'll just quit"
@ -95,6 +93,7 @@ def get_configuration():
"save_pngs" : args.save_pngs,
#If -t is passed in (for transparent), this will be RGBA
"saved_image_mode": "RGBA" if args.transparent else "RGB",
"movie_file_extension" : ".mov" if args.transparent else ".mp4",
"quiet" : args.quiet or args.write_all,
"ignore_waits" : args.preview,
"write_all" : args.write_all,
@ -237,6 +236,7 @@ def main():
"write_to_movie",
"output_directory",
"save_pngs",
"movie_file_extension",
"start_at_animation_number",
"end_at_animation_number",
]
@ -260,4 +260,4 @@ def main():
if __name__ == "__main__":
main()
main()

View file

@ -693,6 +693,7 @@ class DictAsObject(object):
def __init__(self, dict):
self.__dict__ = dict
# Just to have a less heavyweight name for this extremely common operation
#
# We may wish to have more fine-grained control over division by zero behavior
# in the future (separate specifiable values for 0/0 and x/0 with x != 0),
@ -707,7 +708,6 @@ def fdiv(a, b, zero_over_zero_value = None):
return np.true_divide(a, b, out = out, where = where)
def add_extension_if_not_present(file_name, extension):
# This could conceivably be smarter about handling existing differing extensions
if(file_name[-len(extension):] != extension):

View file

@ -389,6 +389,9 @@ class Mobject(Container):
def stretch_to_fit_height(self, height, **kwargs):
return self.rescale_to_fit(height, 1, stretch = True, **kwargs)
def stretch_to_fit_depth(self, depth, **kwargs):
return self.rescale_to_fit(depth, 1, stretch = True, **kwargs)
def scale_to_fit_width(self, width, **kwargs):
return self.rescale_to_fit(width, 0, stretch = False, **kwargs)

View file

@ -37,9 +37,9 @@ class SVGMobject(VMobject):
if self.file_name is None:
raise Exception("Must specify file for SVGMobject")
possible_paths = [
self.file_name,
os.path.join(SVG_IMAGE_DIR, self.file_name),
os.path.join(SVG_IMAGE_DIR, self.file_name + ".svg"),
self.file_name,
]
for path in possible_paths:
if os.path.exists(path):

View file

@ -82,7 +82,7 @@ class Scene(Container):
def setup(self):
"""
This is meant to be implement by any scenes which
are commonly subclassed, and have some common setup
are comonly subclassed, and have some common setup
involved before the construct method is called.
"""
pass
@ -366,7 +366,6 @@ class Scene(Container):
Each arg can either be an animation, or a mobject method
followed by that methods arguments (and potentially follow
by a dict of kwargs for that method).
This animation list is built by going through the args list,
and each animation is simply added, but when a mobject method
s hit, a MoveToTarget animation is built using the args that
@ -387,7 +386,7 @@ class Scene(Container):
animations.pop()
#method should already have target then.
else:
mobject.target = mobject.deepcopy()
mobject.generate_target()
#
if len(state["method_args"]) > 0 and isinstance(state["method_args"][-1], dict):
method_kwargs = state["method_args"].pop()
@ -578,17 +577,12 @@ class Scene(Container):
FFMPEG_BIN,
'-y', # overwrite output file if it exists
'-f', 'rawvideo',
'-vcodec','rawvideo',
'-s', '%dx%d'%(width, height), # size of one frame
'-pix_fmt', 'rgba',
'-r', str(fps), # frames per second
'-i', '-', # The imput comes from a pipe
'-an', # Tells FFMPEG not to expect any audio
'-vcodec', 'mpeg',
'-c:v', 'libx264',
'-pix_fmt', 'yuv420p',
'-loglevel', 'error',
temp_file_path,
]
if self.movie_file_extension == ".mov":
# This is if the background of the exported video
@ -624,4 +618,3 @@ class EndSceneEarlyException(Exception):

View file

@ -123,8 +123,11 @@ class PatreonEndScreen(PatreonThanks):
"n_patron_columns" : 3,
"max_patron_width" : 3,
"run_time" : 20,
"randomize_order" : True,
}
def construct(self):
if self.randomize_order:
random.shuffle(self.specific_patrons)
self.add_title()
self.scroll_through_patrons()
@ -141,7 +144,6 @@ class PatreonEndScreen(PatreonThanks):
pi.next_to(title, vect, buff = MED_LARGE_BUFF)
self.add_foreground_mobjects(title, randy, morty)
def scroll_through_patrons(self):
logo_box = Square(side_length = 2.5)
logo_box.to_corner(DOWN+LEFT, buff = MED_LARGE_BUFF)
@ -176,7 +178,7 @@ class PatreonEndScreen(PatreonThanks):
aligned_edge = UP,
)
columns.scale_to_fit_width(total_width - 1)
columns.next_to(black_rect, DOWN, LARGE_BUFF)
columns.next_to(black_rect, DOWN, 3*LARGE_BUFF)
columns.to_edge(RIGHT)
self.play(

View file

@ -128,7 +128,6 @@ class LightSource(VMobject):
self.camera_mob = new_cam_mob
self.spotlight.camera_mob = new_cam_mob
def set_screen(self, new_screen):
if self.has_screen():
self.spotlight.screen = new_screen
@ -160,9 +159,6 @@ class LightSource(VMobject):
# in any case
self.screen = new_screen
def move_source_to(self,point):
apoint = np.array(point)
v = apoint - self.get_source_point()
@ -195,14 +191,13 @@ class LightSource(VMobject):
self.spotlight.update_sectors()
self.update_shadow()
def update_lighthouse(self):
new_lh = Lighthouse()
new_lh.move_to(ORIGIN)
new_lh.apply_matrix(self.rotation_matrix())
new_lh.shift(self.get_source_point())
self.lighthouse.submobjects = new_lh.submobjects
self.lighthouse.move_to(self.get_source_point())
# new_lh = Lighthouse()
# new_lh.move_to(ORIGIN)
# new_lh.apply_matrix(self.rotation_matrix())
# new_lh.shift(self.get_source_point())
# self.lighthouse.submobjects = new_lh.submobjects
def update_ambient(self):
new_ambient_light = AmbientLight(
@ -217,12 +212,9 @@ class LightSource(VMobject):
new_ambient_light.move_source_to(self.get_source_point())
self.ambient_light.submobjects = new_ambient_light.submobjects
def get_source_point(self):
return self.source_point.get_location()
def rotation_matrix(self):
if self.camera_mob == None:
@ -247,9 +239,7 @@ class LightSource(VMobject):
R = np.dot(R2, R1)
return R
def update_shadow(self):
point = self.get_source_point()
projected_screen_points = []
if not self.has_screen():
@ -319,7 +309,6 @@ class LightSource(VMobject):
self.shadow.mark_paths_closed = True
class SwitchOn(LaggedStart):
CONFIG = {
"lag_ratio": 0.2,
@ -329,9 +318,9 @@ class SwitchOn(LaggedStart):
def __init__(self, light, **kwargs):
if (not isinstance(light,AmbientLight) and not isinstance(light,Spotlight)):
raise Exception("Only AmbientLights and Spotlights can be switched on")
LaggedStart.__init__(self,
FadeIn, light, **kwargs)
LaggedStart.__init__(
self, FadeIn, light, **kwargs
)
class SwitchOff(LaggedStart):
CONFIG = {
@ -347,9 +336,6 @@ class SwitchOff(LaggedStart):
FadeOut, light, **kwargs)
light.submobjects = light.submobjects[::-1]
class Lighthouse(SVGMobject):
CONFIG = {
"file_name" : "lighthouse",
@ -361,7 +347,6 @@ class Lighthouse(SVGMobject):
def move_to(self,point):
self.next_to(point, DOWN, buff = 0)
class AmbientLight(VMobject):
# Parameters are:
@ -377,8 +362,8 @@ class AmbientLight(VMobject):
"opacity_function" : lambda r : 1.0/(r+1.0)**2,
"color" : LIGHT_COLOR,
"max_opacity" : 1.0,
"num_levels" : 10,
"radius" : 10.0
"num_levels" : NUM_LEVELS,
"radius" : 5.0
}
def generate_points(self):
@ -438,21 +423,7 @@ class AmbientLight(VMobject):
submob.set_fill(opacity = new_submob_alpha)
class Spotlight(VMobject):
CONFIG = {
"source_point": VectorizedPoint(location = ORIGIN, stroke_width = 0, fill_opacity = 0),
"opacity_function" : lambda r : 1.0/(r/2+1.0)**2,
@ -481,13 +452,10 @@ class Spotlight(VMobject):
w = project_along_vector(point,v)
return w
def get_source_point(self):
return self.source_point.get_location()
def generate_points(self):
self.submobjects = []
self.add(self.source_point)
@ -503,13 +471,7 @@ class Spotlight(VMobject):
new_sector = self.new_sector(r,dr,lower_angle,upper_angle)
self.add(new_sector)
def new_sector(self,r,dr,lower_angle,upper_angle):
# Note: I'm not looking _too_ closely at the implementation
# of these updates based on viewing angles and such. It seems to
# behave as intended, but let me know if you'd like more thorough
# scrutiny
alpha = self.max_opacity * self.opacity_function(r)
annular_sector = AnnularSector(
inner_radius = r,
@ -545,7 +507,6 @@ class Spotlight(VMobject):
else:
return -absolute_angle
def viewing_angles(self,screen):
screen_points = screen.get_anchors()
@ -572,7 +533,6 @@ class Spotlight(VMobject):
return lower_ray, upper_ray
def opening_angle(self):
l,u = self.viewing_angles(self.screen)
return u - l
@ -592,21 +552,20 @@ class Spotlight(VMobject):
self.update_sectors()
return self
def update_sectors(self):
if self.screen == None:
return
for submob in self.submobject_family():
for submob in self.submobjects:
if type(submob) == AnnularSector:
lower_angle, upper_angle = self.viewing_angles(self.screen)
#dr = submob.outer_radius - submob.inner_radius
dr = self.radius / self.num_levels
new_submob = self.new_sector(submob.inner_radius,dr,lower_angle,upper_angle)
submob.points = new_submob.points
submob.set_fill(opacity = 10 * self.opacity_function(submob.outer_radius))
new_submob = self.new_sector(
submob.inner_radius, dr, lower_angle, upper_angle
)
# submob.points = new_submob.points
# submob.set_fill(opacity = 10 * self.opacity_function(submob.outer_radius))
Transform(submob, new_submob).update(1)
def dimming(self,new_alpha):
old_alpha = self.max_opacity
@ -640,7 +599,27 @@ class Spotlight(VMobject):
class ScreenTracker(ContinualAnimation):
def __init__(self, light_source, **kwargs):
self.light_source = light_source
dummy_mob = Mobject()
ContinualAnimation.__init__(self, dummy_mob, **kwargs)
def update_mobject(self, dt):
self.mobject.update()
self.light_source.update()

View file

@ -144,7 +144,6 @@ class ContinualChangingDecimal(ContinualAnimation):
def update_mobject(self, dt):
self.anim.update(self.internal_time)