mirror of
https://github.com/3b1b/manim.git
synced 2025-08-21 05:44:04 +00:00
Merge branch 'master' of github.com:3b1b/manim into uncertainty
This commit is contained in:
commit
ae6c1d82ea
8 changed files with 58 additions and 44 deletions
|
@ -10,10 +10,6 @@ from helpers import *
|
||||||
from mobject import Mobject, PMobject, VMobject, \
|
from mobject import Mobject, PMobject, VMobject, \
|
||||||
ImageMobject, Group, BackgroundColoredVMobject
|
ImageMobject, Group, BackgroundColoredVMobject
|
||||||
|
|
||||||
# Set a @profile decorator over any method whose
|
|
||||||
# performance you'd like to analyze
|
|
||||||
from profilehooks import profile
|
|
||||||
|
|
||||||
class Camera(object):
|
class Camera(object):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"background_image" : None,
|
"background_image" : None,
|
||||||
|
@ -179,7 +175,6 @@ class Camera(object):
|
||||||
def capture_mobject(self, mobject, **kwargs):
|
def capture_mobject(self, mobject, **kwargs):
|
||||||
return self.capture_mobjects([mobject], **kwargs)
|
return self.capture_mobjects([mobject], **kwargs)
|
||||||
|
|
||||||
@profile
|
|
||||||
def capture_mobjects(self, mobjects, **kwargs):
|
def capture_mobjects(self, mobjects, **kwargs):
|
||||||
self.reset_aggdraw_canvas()
|
self.reset_aggdraw_canvas()
|
||||||
mobjects = self.get_mobjects_to_display(mobjects, **kwargs)
|
mobjects = self.get_mobjects_to_display(mobjects, **kwargs)
|
||||||
|
@ -241,14 +236,22 @@ class Camera(object):
|
||||||
canvas.symbol((0, 0), symbol, pen, fill)
|
canvas.symbol((0, 0), symbol, pen, fill)
|
||||||
|
|
||||||
def get_pen_and_fill(self, vmobject):
|
def get_pen_and_fill(self, vmobject):
|
||||||
pen = aggdraw.Pen(
|
stroke_width = max(vmobject.get_stroke_width(), 0)
|
||||||
self.color_to_hex_l(self.get_stroke_color(vmobject)),
|
if stroke_width == 0:
|
||||||
max(vmobject.stroke_width, 0)
|
pen = None
|
||||||
)
|
else:
|
||||||
fill = aggdraw.Brush(
|
stroke_rgb = self.get_stroke_rgb(vmobject)
|
||||||
self.color_to_hex_l(self.get_fill_color(vmobject)),
|
stroke_hex = rgb_to_hex(stroke_rgb)
|
||||||
opacity = int(self.color_max_val*vmobject.get_fill_opacity())
|
pen = aggdraw.Pen(stroke_hex, stroke_width)
|
||||||
)
|
|
||||||
|
fill_opacity = int(self.color_max_val*vmobject.get_fill_opacity())
|
||||||
|
if fill_opacity == 0:
|
||||||
|
fill = None
|
||||||
|
else:
|
||||||
|
fill_rgb = self.get_fill_rgb(vmobject)
|
||||||
|
fill_hex = rgb_to_hex(fill_rgb)
|
||||||
|
fill = aggdraw.Brush(fill_hex, fill_opacity)
|
||||||
|
|
||||||
return (pen, fill)
|
return (pen, fill)
|
||||||
|
|
||||||
def color_to_hex_l(self, color):
|
def color_to_hex_l(self, color):
|
||||||
|
@ -257,11 +260,11 @@ class Camera(object):
|
||||||
except:
|
except:
|
||||||
return Color(BLACK).get_hex_l()
|
return Color(BLACK).get_hex_l()
|
||||||
|
|
||||||
def get_stroke_color(self, vmobject):
|
def get_stroke_rgb(self, vmobject):
|
||||||
return vmobject.get_stroke_color()
|
return vmobject.get_stroke_rgb()
|
||||||
|
|
||||||
def get_fill_color(self, vmobject):
|
def get_fill_rgb(self, vmobject):
|
||||||
return vmobject.get_fill_color()
|
return vmobject.get_fill_rgb()
|
||||||
|
|
||||||
def get_pathstring(self, vmobject):
|
def get_pathstring(self, vmobject):
|
||||||
result = ""
|
result = ""
|
||||||
|
@ -272,7 +275,7 @@ class Camera(object):
|
||||||
continue
|
continue
|
||||||
aligned_points = self.align_points_to_camera(points)
|
aligned_points = self.align_points_to_camera(points)
|
||||||
coords = self.points_to_pixel_coords(aligned_points)
|
coords = self.points_to_pixel_coords(aligned_points)
|
||||||
coord_strings = coords.flatten().astype("string")
|
coord_strings = coords.flatten().astype(str)
|
||||||
#Start new path string with M
|
#Start new path string with M
|
||||||
coord_strings[0] = "M" + coord_strings[0]
|
coord_strings[0] = "M" + coord_strings[0]
|
||||||
#The C at the start of every 6th number communicates
|
#The C at the start of every 6th number communicates
|
||||||
|
|
|
@ -68,7 +68,7 @@ def get_configuration():
|
||||||
for short_arg, long_arg in optional_args:
|
for short_arg, long_arg in optional_args:
|
||||||
parser.add_argument(short_arg, long_arg, action = "store_true")
|
parser.add_argument(short_arg, long_arg, action = "store_true")
|
||||||
parser.add_argument("-o", "--output_name")
|
parser.add_argument("-o", "--output_name")
|
||||||
parser.add_argument("-n", "--skip_to_animation_number")
|
parser.add_argument("-n", "--start_at_animation_number")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
except argparse.ArgumentError as err:
|
except argparse.ArgumentError as err:
|
||||||
print(str(err))
|
print(str(err))
|
||||||
|
@ -88,7 +88,8 @@ def get_configuration():
|
||||||
"ignore_waits" : args.preview,
|
"ignore_waits" : args.preview,
|
||||||
"write_all" : args.write_all,
|
"write_all" : args.write_all,
|
||||||
"output_name" : args.output_name,
|
"output_name" : args.output_name,
|
||||||
"skip_to_animation_number" : args.skip_to_animation_number,
|
"start_at_animation_number" : args.start_at_animation_number,
|
||||||
|
"end_at_animation_number" : None,
|
||||||
}
|
}
|
||||||
if args.low_quality:
|
if args.low_quality:
|
||||||
config["camera_config"] = LOW_QUALITY_CAMERA_CONFIG
|
config["camera_config"] = LOW_QUALITY_CAMERA_CONFIG
|
||||||
|
@ -100,13 +101,18 @@ def get_configuration():
|
||||||
config["camera_config"] = PRODUCTION_QUALITY_CAMERA_CONFIG
|
config["camera_config"] = PRODUCTION_QUALITY_CAMERA_CONFIG
|
||||||
config["frame_duration"] = PRODUCTION_QUALITY_FRAME_DURATION
|
config["frame_duration"] = PRODUCTION_QUALITY_FRAME_DURATION
|
||||||
|
|
||||||
stan = config["skip_to_animation_number"]
|
stan = config["start_at_animation_number"]
|
||||||
if stan is not None:
|
if stan is not None:
|
||||||
config["skip_to_animation_number"] = int(stan)
|
if "," in stan:
|
||||||
|
start, end = stan.split(",")
|
||||||
|
config["start_at_animation_number"] = int(start)
|
||||||
|
config["end_at_animation_number"] = int(end)
|
||||||
|
else:
|
||||||
|
config["start_at_animation_number"] = int(stan)
|
||||||
|
|
||||||
config["skip_animations"] = any([
|
config["skip_animations"] = any([
|
||||||
config["show_last_frame"] and not config["write_to_movie"],
|
config["show_last_frame"] and not config["write_to_movie"],
|
||||||
config["skip_to_animation_number"],
|
config["start_at_animation_number"],
|
||||||
])
|
])
|
||||||
return config
|
return config
|
||||||
|
|
||||||
|
@ -220,7 +226,8 @@ def main():
|
||||||
"write_to_movie",
|
"write_to_movie",
|
||||||
"output_directory",
|
"output_directory",
|
||||||
"save_pngs",
|
"save_pngs",
|
||||||
"skip_to_animation_number",
|
"start_at_animation_number",
|
||||||
|
"end_at_animation_number",
|
||||||
]
|
]
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ def rgba_to_color(rgba):
|
||||||
return rgb_to_color(rgba[:3])
|
return rgb_to_color(rgba[:3])
|
||||||
|
|
||||||
def rgb_to_hex(rgb):
|
def rgb_to_hex(rgb):
|
||||||
return Color(rgb = rgb).get_hex_l()
|
return "#" + "".join('%02x'%int(255*x) for x in rgb)
|
||||||
|
|
||||||
def invert_color(color):
|
def invert_color(color):
|
||||||
return rgb_to_color(1.0 - color_to_rgb(color))
|
return rgb_to_color(1.0 - color_to_rgb(color))
|
||||||
|
|
|
@ -120,6 +120,9 @@ class VMobject(Mobject):
|
||||||
)
|
)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
def get_fill_rgb(self):
|
||||||
|
return self.fill_rgb
|
||||||
|
|
||||||
def get_fill_color(self):
|
def get_fill_color(self):
|
||||||
try:
|
try:
|
||||||
self.fill_rgb = np.clip(self.fill_rgb, 0.0, 1.0)
|
self.fill_rgb = np.clip(self.fill_rgb, 0.0, 1.0)
|
||||||
|
@ -130,6 +133,9 @@ class VMobject(Mobject):
|
||||||
def get_fill_opacity(self):
|
def get_fill_opacity(self):
|
||||||
return np.clip(self.fill_opacity, 0, 1)
|
return np.clip(self.fill_opacity, 0, 1)
|
||||||
|
|
||||||
|
def get_stroke_rgb(self):
|
||||||
|
return self.stroke_rgb
|
||||||
|
|
||||||
def get_stroke_color(self):
|
def get_stroke_color(self):
|
||||||
try:
|
try:
|
||||||
self.stroke_rgb = np.clip(self.stroke_rgb, 0, 1)
|
self.stroke_rgb = np.clip(self.stroke_rgb, 0, 1)
|
||||||
|
|
|
@ -39,7 +39,8 @@ class Scene(Container):
|
||||||
"name" : None,
|
"name" : None,
|
||||||
"always_continually_update" : False,
|
"always_continually_update" : False,
|
||||||
"random_seed" : 0,
|
"random_seed" : 0,
|
||||||
"skip_to_animation_number" : None,
|
"start_at_animation_number" : None,
|
||||||
|
"end_at_animation_number" : None,
|
||||||
}
|
}
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
Container.__init__(self, **kwargs) # Perhaps allow passing in a non-empty *mobjects parameter?
|
Container.__init__(self, **kwargs) # Perhaps allow passing in a non-empty *mobjects parameter?
|
||||||
|
@ -406,14 +407,17 @@ class Scene(Container):
|
||||||
if len(args) == 0:
|
if len(args) == 0:
|
||||||
warnings.warn("Called Scene.play with no animations")
|
warnings.warn("Called Scene.play with no animations")
|
||||||
return
|
return
|
||||||
if self.skip_to_animation_number:
|
if self.start_at_animation_number:
|
||||||
if self.num_plays + 1 == self.skip_to_animation_number:
|
if self.num_plays == self.start_at_animation_number:
|
||||||
self.skip_animations = False
|
self.skip_animations = False
|
||||||
|
if self.end_at_animation_number:
|
||||||
|
if self.num_plays >= self.end_at_animation_number:
|
||||||
|
self.skip_animations = True
|
||||||
|
return self #Don't even both with the rest...
|
||||||
if self.skip_animations:
|
if self.skip_animations:
|
||||||
kwargs["run_time"] = 0
|
kwargs["run_time"] = 0
|
||||||
|
|
||||||
animations = self.compile_play_args_to_animation_list(*args)
|
animations = self.compile_play_args_to_animation_list(*args)
|
||||||
self.num_plays += 1
|
|
||||||
|
|
||||||
sync_animation_run_times_and_rate_funcs(*animations, **kwargs)
|
sync_animation_run_times_and_rate_funcs(*animations, **kwargs)
|
||||||
moving_mobjects = self.get_moving_mobjects(*animations)
|
moving_mobjects = self.get_moving_mobjects(*animations)
|
||||||
|
@ -429,6 +433,7 @@ class Scene(Container):
|
||||||
self.mobjects_from_last_animation = moving_mobjects
|
self.mobjects_from_last_animation = moving_mobjects
|
||||||
self.clean_up_animations(*animations)
|
self.clean_up_animations(*animations)
|
||||||
self.continual_update(0)
|
self.continual_update(0)
|
||||||
|
self.num_plays += 1
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def clean_up_animations(self, *animations):
|
def clean_up_animations(self, *animations):
|
||||||
|
|
|
@ -136,8 +136,6 @@ class NumberLine(VMobject):
|
||||||
self.tip = tip
|
self.tip = tip
|
||||||
self.add(tip)
|
self.add(tip)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class UnitInterval(NumberLine):
|
class UnitInterval(NumberLine):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"x_min" : 0,
|
"x_min" : 0,
|
||||||
|
|
|
@ -40,22 +40,17 @@ class ThreeDCamera(CameraWithPerspective):
|
||||||
self.rotation_mobject = VectorizedPoint()
|
self.rotation_mobject = VectorizedPoint()
|
||||||
self.set_position(self.phi, self.theta, self.distance)
|
self.set_position(self.phi, self.theta, self.distance)
|
||||||
|
|
||||||
def get_color(self, method):
|
def modified_rgb(self, vmobject, rgb):
|
||||||
color = method()
|
|
||||||
vmobject = method.im_self
|
|
||||||
if should_shade_in_3d(vmobject):
|
if should_shade_in_3d(vmobject):
|
||||||
return Color(rgb = self.get_shaded_rgb(
|
return self.get_shaded_rgb(rgb, self.get_unit_normal_vect(vmobject))
|
||||||
color_to_rgb(color),
|
|
||||||
normal_vect = self.get_unit_normal_vect(vmobject)
|
|
||||||
))
|
|
||||||
else:
|
else:
|
||||||
return color
|
return color
|
||||||
|
|
||||||
def get_stroke_color(self, vmobject):
|
def get_stroke_rgb(self, vmobject):
|
||||||
return self.get_color(vmobject.get_stroke_color)
|
return self.modified_rgb(vmobject, vmobject.get_stroke_rgb())
|
||||||
|
|
||||||
def get_fill_color(self, vmobject):
|
def get_fill_rgb(self, vmobject):
|
||||||
return self.get_color(vmobject.get_fill_color)
|
return self.modified_rgb(vmobject, vmobject.get_fill_rgb())
|
||||||
|
|
||||||
def get_shaded_rgb(self, rgb, normal_vect):
|
def get_shaded_rgb(self, rgb, normal_vect):
|
||||||
brightness = np.dot(normal_vect, self.unit_sun_vect)**2
|
brightness = np.dot(normal_vect, self.unit_sun_vect)**2
|
||||||
|
|
Loading…
Add table
Reference in a new issue