mirror of
https://github.com/3b1b/manim.git
synced 2026-04-26 03:00:23 -04:00
2720
active_projects/quaternions.py
Normal file
2720
active_projects/quaternions.py
Normal file
File diff suppressed because it is too large
Load Diff
@@ -191,6 +191,14 @@ class FadeOutAndShiftDown(FadeOutAndShift):
|
||||
}
|
||||
|
||||
|
||||
class FadeInFromLarge(Transform):
|
||||
def __init__(self, mobject, scale_factor=2, **kwargs):
|
||||
target = mobject.copy()
|
||||
mobject.scale(scale_factor)
|
||||
mobject.fade(1)
|
||||
Transform.__init__(self, mobject, target, **kwargs)
|
||||
|
||||
|
||||
class VFadeIn(Animation):
|
||||
"""
|
||||
VFadeIn and VFadeOut only work for VMobjects, but they can be applied
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
|
||||
from constants import *
|
||||
|
||||
from animation.animation import Animation
|
||||
from utils.bezier import interpolate
|
||||
from utils.config_ops import digest_config
|
||||
|
||||
@@ -51,6 +51,7 @@ from mobject.svg.brace import *
|
||||
from mobject.svg.drawings import *
|
||||
from mobject.svg.svg_mobject import *
|
||||
from mobject.svg.tex_mobject import *
|
||||
from mobject.three_d_utils import *
|
||||
from mobject.three_dimensions import *
|
||||
from mobject.types.image_mobject import *
|
||||
from mobject.types.point_cloud_mobject import *
|
||||
|
||||
@@ -2,14 +2,10 @@
|
||||
import itertools as it
|
||||
import numpy as np
|
||||
import operator as op
|
||||
import copy
|
||||
|
||||
# import aggdraw
|
||||
import copy
|
||||
import time
|
||||
|
||||
from PIL import Image
|
||||
from colour import Color
|
||||
from scipy.spatial.distance import pdist
|
||||
import cairo
|
||||
|
||||
@@ -18,6 +14,7 @@ from mobject.types.image_mobject import AbstractImageMobject
|
||||
from mobject.mobject import Mobject
|
||||
from mobject.types.point_cloud_mobject import PMobject
|
||||
from mobject.types.vectorized_mobject import VMobject
|
||||
from mobject.value_tracker import ValueTracker
|
||||
from utils.color import color_to_int_rgba
|
||||
from utils.color import rgb_to_hex
|
||||
from utils.config_ops import digest_config
|
||||
@@ -203,7 +200,10 @@ class Camera(object):
|
||||
|
||||
####
|
||||
|
||||
def extract_mobject_family_members(self, mobjects, only_those_with_points=False):
|
||||
def extract_mobject_family_members(
|
||||
self, mobjects,
|
||||
only_those_with_points=False,
|
||||
ignore_value_trackers=False):
|
||||
if only_those_with_points:
|
||||
method = Mobject.family_members_with_points
|
||||
else:
|
||||
@@ -213,17 +213,20 @@ class Camera(object):
|
||||
method(m)
|
||||
for m in mobjects
|
||||
if not (isinstance(m, VMobject) and m.is_subpath)
|
||||
if not (ignore_value_trackers and isinstance(m, ValueTracker))
|
||||
])
|
||||
))
|
||||
|
||||
def get_mobjects_to_display(
|
||||
self, mobjects,
|
||||
include_submobjects=True,
|
||||
excluded_mobjects=None,
|
||||
):
|
||||
self, mobjects,
|
||||
include_submobjects=True,
|
||||
ignore_value_trackers=True,
|
||||
excluded_mobjects=None):
|
||||
if include_submobjects:
|
||||
mobjects = self.extract_mobject_family_members(
|
||||
mobjects, only_those_with_points=True
|
||||
mobjects,
|
||||
only_those_with_points=True,
|
||||
ignore_value_trackers=ignore_value_trackers,
|
||||
)
|
||||
if excluded_mobjects:
|
||||
all_excluded = self.extract_mobject_family_members(
|
||||
|
||||
@@ -18,6 +18,7 @@ from utils.space_ops import rotation_about_z
|
||||
from utils.space_ops import rotation_matrix
|
||||
from utils.space_ops import center_of_mass
|
||||
from utils.simple_functions import fdiv
|
||||
from utils.simple_functions import clip_in_place
|
||||
|
||||
|
||||
class ThreeDCamera(Camera):
|
||||
@@ -32,6 +33,7 @@ class ThreeDCamera(Camera):
|
||||
"light_source_start_point": 9 * DOWN + 7 * LEFT + 10 * OUT,
|
||||
"frame_center": ORIGIN,
|
||||
"should_apply_shading": True,
|
||||
"exponential_projection": False,
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -42,7 +44,7 @@ class ThreeDCamera(Camera):
|
||||
self.gamma_tracker = ValueTracker(self.gamma)
|
||||
self.light_source = Point(self.light_source_start_point)
|
||||
self.frame_center = Point(self.frame_center)
|
||||
self.fixed_orientation_mobjects = set()
|
||||
self.fixed_orientation_mobjects = dict()
|
||||
self.fixed_in_frame_mobjects = set()
|
||||
self.reset_rotation_matrix()
|
||||
|
||||
@@ -168,13 +170,17 @@ class ThreeDCamera(Camera):
|
||||
points = np.dot(points, rot_matrix.T)
|
||||
zs = points[:, 2]
|
||||
for i in 0, 1:
|
||||
# Proper projedtion would involve multiplying
|
||||
# x and y by d / (d-z). But for points with high
|
||||
# z value, this causes weird artifacts, and applying
|
||||
# the exponential helps smooth it out.
|
||||
factor = np.exp(zs / distance)
|
||||
lt0 = zs < 0
|
||||
factor[lt0] = (distance / (distance - zs[lt0]))
|
||||
if self.exponential_projection:
|
||||
# Proper projedtion would involve multiplying
|
||||
# x and y by d / (d-z). But for points with high
|
||||
# z value that causes weird artifacts, and applying
|
||||
# the exponential helps smooth it out.
|
||||
factor = np.exp(zs / distance)
|
||||
lt0 = zs < 0
|
||||
factor[lt0] = (distance / (distance - zs[lt0]))
|
||||
else:
|
||||
factor = (distance / (distance - zs))
|
||||
clip_in_place(factor, 0, 10**6)
|
||||
points[:, i] *= factor
|
||||
points += frame_center
|
||||
return points
|
||||
@@ -189,15 +195,33 @@ class ThreeDCamera(Camera):
|
||||
if fixed_in_frame:
|
||||
return points
|
||||
if fixed_orientation:
|
||||
center = center_of_mass(points)
|
||||
# center = center_of_mass(points)
|
||||
center_func = self.fixed_orientation_mobjects[mobject]
|
||||
center = center_func()
|
||||
new_center = self.project_point(center)
|
||||
return points + (new_center - center)
|
||||
else:
|
||||
return self.project_points(points)
|
||||
|
||||
def add_fixed_orientation_mobjects(self, *mobjects):
|
||||
for mobject in self.extract_mobject_family_members(mobjects):
|
||||
self.fixed_orientation_mobjects.add(mobject)
|
||||
def add_fixed_orientation_mobjects(
|
||||
self, *mobjects,
|
||||
use_static_center_func=False,
|
||||
center_func=None):
|
||||
# This prevents the computation of mobject.get_center
|
||||
# every single time a projetion happens
|
||||
def get_static_center_func(mobject):
|
||||
point = mobject.get_center()
|
||||
return (lambda: point)
|
||||
|
||||
for mobject in mobjects:
|
||||
if center_func:
|
||||
func = center_func
|
||||
elif use_static_center_func:
|
||||
func = get_static_center_func(mobject)
|
||||
else:
|
||||
func = mobject.get_center
|
||||
for submob in mobject.get_family():
|
||||
self.fixed_orientation_mobjects[submob] = func
|
||||
|
||||
def add_fixed_in_frame_mobjects(self, *mobjects):
|
||||
for mobject in self.extract_mobject_family_members(mobjects):
|
||||
|
||||
@@ -140,7 +140,7 @@ with open(TEMPLATE_TEX_FILE, "r") as infile:
|
||||
TEMPLATE_TEXT_FILE_BODY = infile.read()
|
||||
TEMPLATE_TEX_FILE_BODY = TEMPLATE_TEXT_FILE_BODY.replace(
|
||||
TEX_TEXT_TO_REPLACE,
|
||||
"$${}$$".format(TEX_TEXT_TO_REPLACE)
|
||||
"\\begin{align*}" + TEX_TEXT_TO_REPLACE + "\\end{align*}",
|
||||
)
|
||||
|
||||
FFMPEG_BIN = "ffmpeg"
|
||||
|
||||
@@ -305,49 +305,63 @@ class ThreeLeggedPiCreature(PiCreature):
|
||||
class Eyes(VMobject):
|
||||
CONFIG = {
|
||||
"height": 0.3,
|
||||
"thing_looked_at": None,
|
||||
"thing_to_look_at": None,
|
||||
"mode": "plain",
|
||||
}
|
||||
|
||||
def __init__(self, mobject, **kwargs):
|
||||
def __init__(self, body, **kwargs):
|
||||
VMobject.__init__(self, **kwargs)
|
||||
self.mobject = mobject
|
||||
self.submobjects = self.get_eyes().submobjects
|
||||
self.body = body
|
||||
eyes = self.create_eyes()
|
||||
self.become(eyes, copy_submobjects=False)
|
||||
|
||||
def get_eyes(self, mode=None, thing_to_look_at=None):
|
||||
mode = mode or self.mode
|
||||
def create_eyes(self, mode=None, thing_to_look_at=None):
|
||||
if mode is None:
|
||||
mode = self.mode
|
||||
if thing_to_look_at is None:
|
||||
thing_to_look_at = self.thing_looked_at
|
||||
thing_to_look_at = self.thing_to_look_at
|
||||
self.thing_to_look_at = thing_to_look_at
|
||||
self.mode = mode
|
||||
looking_direction = None
|
||||
|
||||
pi = Randolph(mode=mode)
|
||||
pi = PiCreature(mode=mode)
|
||||
eyes = VGroup(pi.eyes, pi.pupils)
|
||||
pi.scale(self.height / eyes.get_height())
|
||||
if self.submobjects:
|
||||
eyes.match_height(self)
|
||||
eyes.move_to(self, DOWN)
|
||||
looking_direction = self[1].get_center() - self[0].get_center()
|
||||
else:
|
||||
eyes.move_to(self.mobject.get_top(), DOWN)
|
||||
eyes.set_height(self.height)
|
||||
eyes.move_to(self.body.get_top(), DOWN)
|
||||
|
||||
height = eyes.get_height()
|
||||
if thing_to_look_at is not None:
|
||||
pi.look_at(thing_to_look_at)
|
||||
elif looking_direction is not None:
|
||||
pi.look(looking_direction)
|
||||
eyes.set_height(height)
|
||||
|
||||
return eyes
|
||||
|
||||
def change_mode_anim(self, mode, **kwargs):
|
||||
self.mode = mode
|
||||
return Transform(self, self.get_eyes(mode=mode), **kwargs)
|
||||
|
||||
def look_at_anim(self, point_or_mobject, **kwargs):
|
||||
self.thing_looked_at = point_or_mobject
|
||||
return Transform(
|
||||
self, self.get_eyes(thing_to_look_at=point_or_mobject),
|
||||
**kwargs
|
||||
def change_mode(self, mode, thing_to_look_at=None):
|
||||
new_eyes = self.create_eyes(
|
||||
mode=mode,
|
||||
thing_to_look_at=thing_to_look_at
|
||||
)
|
||||
self.become(new_eyes, copy_submobjects=False)
|
||||
return self
|
||||
|
||||
def blink_anim(self, **kwargs):
|
||||
target = self.copy()
|
||||
def look_at(self, thing_to_look_at):
|
||||
self.change_mode(
|
||||
self.mode,
|
||||
thing_to_look_at=thing_to_look_at
|
||||
)
|
||||
return self
|
||||
|
||||
def blink(self, **kwargs): # TODO, change Blink
|
||||
bottom_y = self.get_bottom()[1]
|
||||
for submob in target:
|
||||
for submob in self:
|
||||
submob.apply_function(
|
||||
lambda p: [p[0], bottom_y, p[2]]
|
||||
)
|
||||
if "rate_func" not in kwargs:
|
||||
kwargs["rate_func"] = squish_rate_func(there_and_back)
|
||||
return Transform(self, target, **kwargs)
|
||||
return self
|
||||
|
||||
@@ -63,12 +63,14 @@ class PiCreatureScene(Scene):
|
||||
return self.pi_creatures[0]
|
||||
|
||||
def any_pi_creatures_on_screen(self):
|
||||
mobjects = self.get_mobjects()
|
||||
return any([pi in mobjects for pi in self.get_pi_creatures()])
|
||||
return len(self.get_on_screen_pi_creatures()) > 0
|
||||
|
||||
def get_on_screen_pi_creatures(self):
|
||||
mobjects = self.get_mobjects()
|
||||
return VGroup(*[pi for pi in self.get_pi_creatures() if pi in mobjects])
|
||||
mobjects = self.get_mobject_family_members()
|
||||
return VGroup(*[
|
||||
pi for pi in self.get_pi_creatures()
|
||||
if pi in mobjects
|
||||
])
|
||||
|
||||
def introduce_bubble(self, *args, **kwargs):
|
||||
if isinstance(args[0], PiCreature):
|
||||
|
||||
@@ -48,16 +48,18 @@ class Axes(VGroup):
|
||||
config.update(extra_config)
|
||||
return NumberLine(x_min=min_val, x_max=max_val, **config)
|
||||
|
||||
def coords_to_point(self, x, y):
|
||||
def coords_to_point(self, *coords):
|
||||
origin = self.x_axis.number_to_point(0)
|
||||
x_axis_projection = self.x_axis.number_to_point(x)
|
||||
y_axis_projection = self.y_axis.number_to_point(y)
|
||||
return x_axis_projection + y_axis_projection - origin
|
||||
result = np.array(origin)
|
||||
for axis, coord in zip(self, coords):
|
||||
result += (axis.number_to_point(coord) - origin)
|
||||
return result
|
||||
|
||||
def point_to_coords(self, point):
|
||||
return tuple([
|
||||
axis.point_to_number(point)
|
||||
for axis in self
|
||||
if isinstance(axis, NumberLine)
|
||||
])
|
||||
|
||||
def get_graph(
|
||||
@@ -137,9 +139,10 @@ class ThreeDAxes(Axes):
|
||||
|
||||
def add_3d_pieces(self):
|
||||
for axis in self:
|
||||
axis.add(VGroup(
|
||||
axis.pieces = VGroup(
|
||||
*axis.main_line.get_pieces(self.num_axis_pieces)
|
||||
))
|
||||
)
|
||||
axis.add(axis.pieces)
|
||||
axis.main_line.set_stroke(width=0, family=False)
|
||||
for submob in axis.family_members_with_points():
|
||||
submob.shade_in_3d = True
|
||||
@@ -364,10 +367,11 @@ class ComplexPlane(NumberPlane):
|
||||
numbers += [
|
||||
complex(0, y)
|
||||
for y in range(-int(self.y_radius), int(self.y_radius) + 1)
|
||||
if y != 0
|
||||
]
|
||||
for number in numbers:
|
||||
if number == complex(0, 0):
|
||||
continue
|
||||
# if number == complex(0, 0):
|
||||
# continue
|
||||
point = self.number_to_point(number)
|
||||
num_str = str(number).replace("j", "i")
|
||||
if num_str.startswith("0"):
|
||||
|
||||
@@ -600,7 +600,7 @@ class Arrow(Line):
|
||||
return self
|
||||
|
||||
def get_normal_vector(self):
|
||||
p0, p1, p2 = self.tip[0].get_anchors()
|
||||
p0, p1, p2 = self.tip[0].get_anchors()[:3]
|
||||
result = np.cross(p2 - p1, p1 - p0)
|
||||
norm = get_norm(result)
|
||||
if norm == 0:
|
||||
|
||||
@@ -170,8 +170,11 @@ class Mobject(Container):
|
||||
def get_updaters(self):
|
||||
return self.updaters
|
||||
|
||||
def add_updater(self, update_function):
|
||||
def add_updater(self, update_function, call_updater=True):
|
||||
self.updaters.append(update_function)
|
||||
if call_updater:
|
||||
self.update(0)
|
||||
return self
|
||||
|
||||
def remove_updater(self, update_function):
|
||||
while update_function in self.updaters:
|
||||
@@ -854,11 +857,11 @@ class Mobject(Container):
|
||||
submob.shuffle_submobjects(recursive=True)
|
||||
random.shuffle(self.submobjects)
|
||||
|
||||
def print_get_family(self, n_tabs=0):
|
||||
def print_submobject_family(self, n_tabs=0):
|
||||
"""For debugging purposes"""
|
||||
print("\t" * n_tabs, self, id(self))
|
||||
for submob in self.submobjects:
|
||||
submob.print_get_family(n_tabs + 1)
|
||||
submob.print_submobject_family(n_tabs + 1)
|
||||
|
||||
# Alignment
|
||||
def align_data(self, mobject):
|
||||
@@ -972,14 +975,15 @@ class Mobject(Container):
|
||||
def pointwise_become_partial(self, mobject, a, b):
|
||||
pass # To implement in subclass
|
||||
|
||||
def become(self, mobject):
|
||||
def become(self, mobject, copy_submobjects=True):
|
||||
"""
|
||||
Edit points, colors and submobjects to be idential
|
||||
to another mobject
|
||||
"""
|
||||
self.align_points(mobject)
|
||||
self.interpolate(self, mobject, 1)
|
||||
self.submobjects = [sm.copy() for sm in mobject.submobjects]
|
||||
self.align_data(mobject)
|
||||
for sm1, sm2 in zip(self.get_family(), mobject.get_family()):
|
||||
sm1.interpolate(sm1, sm2, 1)
|
||||
return self
|
||||
|
||||
|
||||
class Group(Mobject):
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from constants import *
|
||||
|
||||
from mobject.svg.tex_mobject import TexMobject
|
||||
from mobject.numbers import DecimalNumber
|
||||
from mobject.types.vectorized_mobject import VGroup
|
||||
from mobject.types.vectorized_mobject import VMobject
|
||||
from mobject.geometry import Arrow
|
||||
@@ -10,6 +10,8 @@ from mobject.geometry import Line
|
||||
from utils.bezier import interpolate
|
||||
from utils.config_ops import digest_config
|
||||
from utils.space_ops import get_norm
|
||||
from utils.space_ops import normalize
|
||||
from utils.simple_functions import fdiv
|
||||
|
||||
|
||||
class NumberLine(VMobject):
|
||||
@@ -31,6 +33,9 @@ class NumberLine(VMobject):
|
||||
"line_to_number_buff": MED_SMALL_BUFF,
|
||||
"include_tip": False,
|
||||
"propagate_style_to_family": True,
|
||||
"decimal_number_config": {
|
||||
"num_decimal_places": 0,
|
||||
}
|
||||
}
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
@@ -118,11 +123,11 @@ class NumberLine(VMobject):
|
||||
# TODO, handle decimals
|
||||
if len(numbers) == 0:
|
||||
numbers = self.default_numbers_to_display()
|
||||
if "force_integers" in kwargs and kwargs["force_integers"]:
|
||||
numbers = list(map(int, numbers))
|
||||
result = VGroup()
|
||||
for number in numbers:
|
||||
mob = TexMobject(str(number))
|
||||
mob = DecimalNumber(
|
||||
number, **self.decimal_number_config
|
||||
)
|
||||
mob.scale(self.number_scale_val)
|
||||
mob.next_to(
|
||||
self.number_to_point(number),
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
|
||||
|
||||
from constants import *
|
||||
import operator as op
|
||||
|
||||
from mobject.svg.tex_mobject import SingleStringTexMobject
|
||||
from mobject.types.vectorized_mobject import VMobject
|
||||
from functools import reduce
|
||||
|
||||
|
||||
class DecimalNumber(VMobject):
|
||||
@@ -17,6 +13,7 @@ class DecimalNumber(VMobject):
|
||||
"show_ellipsis": False,
|
||||
"unit": None, # Aligned to bottom unless it starts with "^"
|
||||
"include_background_rectangle": False,
|
||||
"edge_to_fix": LEFT,
|
||||
}
|
||||
|
||||
def __init__(self, number, **kwargs):
|
||||
@@ -30,7 +27,8 @@ class DecimalNumber(VMobject):
|
||||
formatter = self.get_formatter()
|
||||
num_string = formatter.format(number)
|
||||
|
||||
if num_string.startswith("-") and number == 0:
|
||||
shows_zero = np.round(number, self.num_decimal_places) == 0
|
||||
if num_string.startswith("-") and shows_zero:
|
||||
num_string = num_string[1:]
|
||||
|
||||
self.add(*[
|
||||
@@ -101,14 +99,20 @@ class DecimalNumber(VMobject):
|
||||
])
|
||||
|
||||
def set_value(self, number, **config):
|
||||
full_config = dict(self.initial_config)
|
||||
full_config = dict(self.CONFIG)
|
||||
full_config.update(self.initial_config)
|
||||
full_config.update(config)
|
||||
new_decimal = DecimalNumber(number, **full_config)
|
||||
new_decimal.match_height(self)
|
||||
new_decimal.move_to(self, LEFT)
|
||||
new_decimal.move_to(self, self.edge_to_fix)
|
||||
new_decimal.match_style(self)
|
||||
|
||||
old_family = self.get_family()
|
||||
self.submobjects = new_decimal.submobjects
|
||||
for mob in old_family:
|
||||
# Dumb hack...due to how scene handles families
|
||||
# of animated mobjects
|
||||
mob.points[:] = 0
|
||||
self.number = number
|
||||
|
||||
def get_value(self):
|
||||
|
||||
@@ -81,7 +81,10 @@ class SingleStringTexMobject(SVGMobject):
|
||||
|
||||
# Handle imbalanced \left and \right
|
||||
num_lefts, num_rights = [
|
||||
len([s for s in tex.split(substr)[1:] if s[0] in "(){}[]|.\\"])
|
||||
len([
|
||||
s for s in tex.split(substr)[1:]
|
||||
if s and s[0] in "(){}[]|.\\"
|
||||
])
|
||||
for substr in ("\\left", "\\right")
|
||||
]
|
||||
if num_lefts != num_rights:
|
||||
|
||||
@@ -44,7 +44,7 @@ class ParametricSurface(VGroup):
|
||||
def setup_in_uv_space(self):
|
||||
res = tuplify(self.resolution)
|
||||
if len(res) == 1:
|
||||
u_res = v_res = res
|
||||
u_res = v_res = res[0]
|
||||
else:
|
||||
u_res, v_res = res
|
||||
u_min = self.u_min
|
||||
|
||||
@@ -640,7 +640,7 @@ class VectorizedPoint(VMobject):
|
||||
return self.artificial_height
|
||||
|
||||
def get_location(self):
|
||||
return self.get_anchors()[0]
|
||||
return self.points[0]
|
||||
|
||||
def set_location(self, new_loc):
|
||||
self.set_points(np.array([new_loc]))
|
||||
|
||||
@@ -1273,7 +1273,7 @@ class WrapCosineGraphAroundCircle(FourierMachineScene):
|
||||
def get_winding_frequency_label(self):
|
||||
freq = self.initial_winding_frequency
|
||||
winding_freq_label = VGroup(
|
||||
DecimalNumber(freq, num_decimal_places = 2),
|
||||
DecimalNumber(freq, num_decimal_places=2),
|
||||
TextMobject("cycles/second")
|
||||
)
|
||||
winding_freq_label.arrange_submobjects(RIGHT)
|
||||
@@ -1639,8 +1639,14 @@ class DrawFrequencyPlot(WrapCosineGraphAroundCircle, PiCreatureScene):
|
||||
added_anims = kwargs.get("added_anims", [])
|
||||
anims = [self.get_frequency_change_animation(self.graph, new_freq)]
|
||||
if hasattr(self, "winding_freq_label"):
|
||||
freq_label = [sm for sm in self.winding_freq_label if isinstance(sm, DecimalNumber)][0]
|
||||
anims.append(ChangeDecimalToValue(freq_label, new_freq))
|
||||
freq_label = [
|
||||
sm for sm in self.winding_freq_label
|
||||
if isinstance(sm, DecimalNumber)
|
||||
][0]
|
||||
self.add(freq_label)
|
||||
anims.append(
|
||||
ChangeDecimalToValue(freq_label, new_freq)
|
||||
)
|
||||
if hasattr(self, "v_lines_indicating_periods"):
|
||||
anims.append(self.get_period_v_lines_update_anim())
|
||||
if hasattr(self, "center_of_mass_dot"):
|
||||
@@ -1838,8 +1844,8 @@ class ShowLinearity(DrawFrequencyPlot):
|
||||
"high_freq_color": YELLOW,
|
||||
"low_freq_color": PINK,
|
||||
"sum_color": GREEN,
|
||||
"low_freq" : 2.0,
|
||||
"high_freq" : 3.0,
|
||||
"low_freq" : 3.0,
|
||||
"high_freq" : 4.0,
|
||||
"circle_plane_config" : {
|
||||
"x_radius" : 2.5,
|
||||
"y_radius" : 2.7,
|
||||
|
||||
@@ -350,7 +350,7 @@ class Scene(Container):
|
||||
# point forward.
|
||||
animation_mobjects = [anim.mobject for anim in animations]
|
||||
ca_mobjects = [ca.mobject for ca in self.continual_animations]
|
||||
mobjects = self.get_mobjects()
|
||||
mobjects = self.get_mobject_family_members()
|
||||
for i, mob in enumerate(mobjects):
|
||||
update_possibilities = [
|
||||
mob in animation_mobjects,
|
||||
|
||||
@@ -22,7 +22,7 @@ class ThreeDScene(Scene):
|
||||
if gamma is not None:
|
||||
self.camera.set_gamma(gamma)
|
||||
|
||||
def begin_ambient_camera_rotation(self, rate=0.1):
|
||||
def begin_ambient_camera_rotation(self, rate=0.05):
|
||||
self.ambient_camera_rotation = ContinualGrowValue(
|
||||
self.camera.theta_tracker,
|
||||
rate=rate
|
||||
@@ -73,8 +73,8 @@ class ThreeDScene(Scene):
|
||||
return self.mobjects
|
||||
return moving_mobjects
|
||||
|
||||
def add_fixed_orientation_mobjects(self, *mobjects):
|
||||
self.camera.add_fixed_orientation_mobjects(*mobjects)
|
||||
def add_fixed_orientation_mobjects(self, *mobjects, **kwargs):
|
||||
self.camera.add_fixed_orientation_mobjects(*mobjects, **kwargs)
|
||||
|
||||
def add_fixed_in_frame_mobjects(self, *mobjects):
|
||||
self.camera.add_fixed_in_frame_mobjects(*mobjects)
|
||||
|
||||
Reference in New Issue
Block a user