mirror of
https://github.com/3b1b/manim.git
synced 2025-09-01 00:48:45 +00:00
Implmented doppler radar pluse for uncertainty
This commit is contained in:
parent
1bea7fc8c5
commit
e78cb80701
1 changed files with 122 additions and 4 deletions
|
@ -136,10 +136,97 @@ class ProbabalisticVectorCloud(ProbabalisticMobjectCloud):
|
|||
class RadarDish(SVGMobject):
|
||||
CONFIG = {
|
||||
"file_name" : "radar_dish",
|
||||
"color" : LIGHT_GREY,
|
||||
"fill_color" : LIGHT_GREY,
|
||||
"stroke_color" : WHITE,
|
||||
"stroke_width" : 1,
|
||||
"height" : 1,
|
||||
}
|
||||
|
||||
|
||||
class RadarPulseSingleton(ContinualAnimation):
|
||||
CONFIG = {
|
||||
"speed" : 3.0,
|
||||
"direction" : RIGHT,
|
||||
"start_up_time" : 0,
|
||||
"fade_in_time" : 0.5,
|
||||
"color" : WHITE,
|
||||
"stroke_width" : 3,
|
||||
}
|
||||
def __init__(self, radar_dish, target, **kwargs):
|
||||
digest_config(self, kwargs)
|
||||
self.direction = self.direction/np.linalg.norm(self.direction)
|
||||
self.radar_dish = radar_dish
|
||||
self.target = target
|
||||
self.reflection_distance = None
|
||||
self.arc = Arc(
|
||||
start_angle = -30*DEGREES,
|
||||
angle = 60*DEGREES,
|
||||
)
|
||||
self.arc.scale_to_fit_height(0.75*radar_dish.get_height())
|
||||
self.arc.move_to(radar_dish, UP+RIGHT)
|
||||
self.start_points = np.array(self.arc.points)
|
||||
self.start_center = self.arc.get_center()
|
||||
self.finished = False
|
||||
|
||||
ContinualAnimation.__init__(self, self.arc, **kwargs)
|
||||
|
||||
def update_mobject(self, dt):
|
||||
arc = self.arc
|
||||
total_distance = self.speed*self.internal_time
|
||||
arc.points = np.array(self.start_points)
|
||||
arc.shift(total_distance*self.direction)
|
||||
|
||||
if self.internal_time < self.fade_in_time:
|
||||
alpha = np.clip(self.internal_time/self.fade_in_time, 0, 1)
|
||||
arc.set_stroke(self.color, alpha*self.stroke_width)
|
||||
|
||||
if self.reflection_distance is None:
|
||||
#Check if reflection is happening
|
||||
arc_point = arc.get_edge_center(self.direction)
|
||||
target_point = self.target.get_edge_center(-self.direction)
|
||||
arc_distance = np.dot(arc_point, self.direction)
|
||||
target_distance = np.dot(target_point, self.direction)
|
||||
if arc_distance > target_distance:
|
||||
self.reflection_distance = target_distance
|
||||
#Don't use elif in case the above code creates reflection_distance
|
||||
if self.reflection_distance is not None:
|
||||
delta_distance = total_distance - self.reflection_distance
|
||||
point_distances = np.dot(self.direction, arc.points.T)
|
||||
diffs = point_distances - self.reflection_distance
|
||||
shift_vals = np.outer(-2*np.maximum(diffs, 0), self.direction)
|
||||
arc.points += shift_vals
|
||||
|
||||
#Check if done
|
||||
arc_point = arc.get_edge_center(-self.direction)
|
||||
if np.dot(arc_point, self.direction) < np.dot(self.start_center, self.direction):
|
||||
self.finished = True
|
||||
self.arc.fade(1)
|
||||
|
||||
def is_finished(self):
|
||||
return self.finished
|
||||
|
||||
class RadarPulse(ContinualAnimation):
|
||||
CONFIG = {
|
||||
"n_pulse_singletons" : 8,
|
||||
"frequency" : 0.05,
|
||||
"colors" : [BLUE, YELLOW]
|
||||
}
|
||||
def __init__(self, *args, **kwargs):
|
||||
digest_config(self, kwargs)
|
||||
colors = color_gradient(self.colors, self.n_pulse_singletons)
|
||||
self.pulse_singletons = [
|
||||
RadarPulseSingleton(*args, color = color, **kwargs)
|
||||
for color in colors
|
||||
]
|
||||
pluse_mobjects = VGroup(*[ps.mobject for ps in self.pulse_singletons])
|
||||
ContinualAnimation.__init__(self, pluse_mobjects, **kwargs)
|
||||
|
||||
def update_mobject(self, dt):
|
||||
for i, ps in enumerate(self.pulse_singletons):
|
||||
ps.internal_time = self.internal_time - i*self.frequency
|
||||
ps.update_mobject(dt)
|
||||
|
||||
def is_finished(self):
|
||||
return all([ps.is_finished() for ps in self.pulse_singletons])
|
||||
|
||||
###################
|
||||
|
||||
|
@ -424,15 +511,46 @@ class ShowPlan(PiCreatureScene):
|
|||
morty = self.pi_creature
|
||||
|
||||
radar_dish = RadarDish()
|
||||
radar_dish.next_to(to_fade, RIGHT)
|
||||
self.add(radar_dish)
|
||||
radar_dish.next_to(word, DOWN, aligned_edge = LEFT)
|
||||
target = Square(stroke_width = 0)
|
||||
target.set_fill(LIGHT_GREY, 1)
|
||||
target.match_height(radar_dish)
|
||||
target.next_to(radar_dish, RIGHT, buff = 0)
|
||||
target_fade = UpdateFromAlphaFunc(
|
||||
target, lambda m, a : m.set_fill(opacity = a)
|
||||
)
|
||||
target_movement = AmbientMovement(target, direction = RIGHT, rate = 1.5)
|
||||
|
||||
pulse = RadarPulse(radar_dish, target)
|
||||
|
||||
checkmark = self.get_checkmark(word)
|
||||
|
||||
self.add(target_movement)
|
||||
self.play(
|
||||
to_fade.fade, 0.5,
|
||||
Write(word),
|
||||
DrawBorderThenFill(radar_dish),
|
||||
target_fade,
|
||||
morty.change, "pondering",
|
||||
run_time = 1
|
||||
)
|
||||
self.add(pulse)
|
||||
while not pulse.is_finished():
|
||||
self.play(
|
||||
morty.look_at, pulse.mobject,
|
||||
run_time = 0.5
|
||||
)
|
||||
self.wait()
|
||||
target_fade.rate_func = lambda a : smooth(1-a)
|
||||
self.play(
|
||||
Write(checkmark),
|
||||
target_fade,
|
||||
morty.change, "happy"
|
||||
)
|
||||
self.wait()
|
||||
|
||||
|
||||
|
||||
|
||||
def play_quantum_anims(self, word, to_fade):
|
||||
pass
|
||||
|
|
Loading…
Add table
Reference in a new issue