2019-02-10 10:26:29 -08:00
|
|
|
import operator as op
|
|
|
|
|
|
|
|
from manimlib.animation.composition import LaggedStart
|
2018-12-24 12:37:51 -08:00
|
|
|
from manimlib.animation.transform import ApplyMethod
|
2019-02-10 10:26:29 -08:00
|
|
|
from manimlib.animation.transform import Restore
|
|
|
|
from manimlib.constants import WHITE
|
|
|
|
from manimlib.constants import BLACK
|
2018-12-24 12:37:51 -08:00
|
|
|
from manimlib.mobject.geometry import Circle
|
|
|
|
from manimlib.mobject.svg.drawings import Car
|
|
|
|
from manimlib.mobject.types.vectorized_mobject import VGroup
|
|
|
|
from manimlib.utils.config_ops import digest_config
|
|
|
|
from manimlib.utils.space_ops import get_norm
|
2018-03-31 18:05:02 -07:00
|
|
|
|
2018-04-06 13:58:59 -07:00
|
|
|
|
2018-03-31 18:05:02 -07:00
|
|
|
class MoveCar(ApplyMethod):
|
|
|
|
CONFIG = {
|
2018-04-06 13:58:59 -07:00
|
|
|
"moving_forward": True,
|
2019-02-10 10:26:29 -08:00
|
|
|
"run_time": 5,
|
2018-03-31 18:05:02 -07:00
|
|
|
}
|
2018-04-06 13:58:59 -07:00
|
|
|
|
2018-03-31 18:05:02 -07:00
|
|
|
def __init__(self, car, target_point, **kwargs):
|
2019-02-10 10:26:29 -08:00
|
|
|
self.check_if_input_is_car(car)
|
|
|
|
self.target_point = target_point
|
|
|
|
super().__init__(car.move_to, target_point, **kwargs)
|
|
|
|
|
|
|
|
def check_if_input_is_car(self, car):
|
|
|
|
if not isinstance(car, Car):
|
|
|
|
raise Exception("MoveCar must take in Car object")
|
|
|
|
|
|
|
|
def begin(self):
|
|
|
|
super().begin()
|
|
|
|
car = self.mobject
|
|
|
|
distance = get_norm(op.sub(
|
|
|
|
self.target_mobject.get_right(),
|
|
|
|
self.starting_mobject.get_right(),
|
|
|
|
))
|
2018-03-31 18:05:02 -07:00
|
|
|
if not self.moving_forward:
|
|
|
|
distance *= -1
|
2018-04-06 13:58:59 -07:00
|
|
|
tire_radius = car.get_tires()[0].get_width() / 2
|
|
|
|
self.total_tire_radians = -distance / tire_radius
|
2018-03-31 18:05:02 -07:00
|
|
|
|
2019-02-08 11:57:27 -08:00
|
|
|
def interpolate_mobject(self, alpha):
|
|
|
|
ApplyMethod.interpolate_mobject(self, alpha)
|
2018-03-31 18:05:02 -07:00
|
|
|
if alpha == 0:
|
|
|
|
return
|
2018-04-06 13:58:59 -07:00
|
|
|
radians = alpha * self.total_tire_radians
|
2018-03-31 18:05:02 -07:00
|
|
|
for tire in self.mobject.get_tires():
|
|
|
|
tire.rotate_in_place(radians)
|
|
|
|
|
2018-04-06 13:58:59 -07:00
|
|
|
|
2019-02-10 10:26:29 -08:00
|
|
|
class Broadcast(LaggedStart):
|
2018-03-31 18:05:02 -07:00
|
|
|
CONFIG = {
|
2018-04-06 13:58:59 -07:00
|
|
|
"small_radius": 0.0,
|
|
|
|
"big_radius": 5,
|
|
|
|
"n_circles": 5,
|
|
|
|
"start_stroke_width": 8,
|
|
|
|
"color": WHITE,
|
|
|
|
"remover": True,
|
2019-02-10 10:26:29 -08:00
|
|
|
"lag_ratio": 0.2,
|
2018-04-06 13:58:59 -07:00
|
|
|
"run_time": 3,
|
|
|
|
"remover": True,
|
2018-03-31 18:05:02 -07:00
|
|
|
}
|
2018-04-06 13:58:59 -07:00
|
|
|
|
2018-03-31 18:05:02 -07:00
|
|
|
def __init__(self, focal_point, **kwargs):
|
|
|
|
digest_config(self, kwargs)
|
|
|
|
circles = VGroup()
|
|
|
|
for x in range(self.n_circles):
|
|
|
|
circle = Circle(
|
2018-04-06 13:58:59 -07:00
|
|
|
radius=self.big_radius,
|
|
|
|
stroke_color=BLACK,
|
|
|
|
stroke_width=0,
|
2018-03-31 18:05:02 -07:00
|
|
|
)
|
2019-02-10 10:26:29 -08:00
|
|
|
circle.add_updater(
|
|
|
|
lambda c: c.move_to(focal_point)
|
|
|
|
)
|
2018-03-31 18:05:02 -07:00
|
|
|
circle.save_state()
|
2018-08-08 10:30:52 -07:00
|
|
|
circle.set_width(self.small_radius * 2)
|
2018-03-31 18:05:02 -07:00
|
|
|
circle.set_stroke(self.color, self.start_stroke_width)
|
|
|
|
circles.add(circle)
|
2019-02-10 10:26:29 -08:00
|
|
|
animations = [
|
|
|
|
Restore(circle)
|
|
|
|
for circle in circles
|
|
|
|
]
|
|
|
|
super().__init__(*animations, **kwargs)
|