mirror of
https://github.com/3b1b/manim.git
synced 2025-07-29 21:12:35 +08:00
Reorganized files for 3b1b videos into a 3b1b_projects folder
This commit is contained in:
495
3b1b_projects/old/brachistochrone/misc.py
Normal file
495
3b1b_projects/old/brachistochrone/misc.py
Normal file
@ -0,0 +1,495 @@
|
||||
import numpy as np
|
||||
import itertools as it
|
||||
|
||||
from manimlib.imports import *
|
||||
from old_projects.brachistochrone.curves import Cycloid
|
||||
|
||||
class PhysicalIntuition(Scene):
|
||||
def construct(self):
|
||||
n_terms = 4
|
||||
def func(xxx_todo_changeme):
|
||||
(x, y, ignore) = xxx_todo_changeme
|
||||
z = complex(x, y)
|
||||
if (np.abs(x%1 - 0.5)<0.01 and y < 0.01) or np.abs(z)<0.01:
|
||||
return ORIGIN
|
||||
out_z = 1./(2*np.tan(np.pi*z)*(z**2))
|
||||
return out_z.real*RIGHT - out_z.imag*UP
|
||||
arrows = Mobject(*[
|
||||
Arrow(ORIGIN, np.sqrt(2)*point)
|
||||
for point in compass_directions(4, RIGHT+UP)
|
||||
])
|
||||
arrows.set_color(YELLOW)
|
||||
arrows.ingest_submobjects()
|
||||
all_arrows = Mobject(*[
|
||||
arrows.copy().scale(0.3/(x)).shift(x*RIGHT)
|
||||
for x in range(1, n_terms+2)
|
||||
])
|
||||
terms = TexMobject([
|
||||
"\\dfrac{1}{%d^2} + "%(x+1)
|
||||
for x in range(n_terms)
|
||||
]+["\\cdots"])
|
||||
terms.shift(2*UP)
|
||||
plane = NumberPlane(color = BLUE_E)
|
||||
axes = Mobject(NumberLine(), NumberLine().rotate(np.pi/2))
|
||||
axes.set_color(WHITE)
|
||||
|
||||
for term in terms.split():
|
||||
self.play(ShimmerIn(term, run_time = 0.5))
|
||||
self.wait()
|
||||
self.play(ShowCreation(plane), ShowCreation(axes))
|
||||
self.play(*[
|
||||
Transform(*pair)
|
||||
for pair in zip(terms.split(), all_arrows.split())
|
||||
])
|
||||
self.play(PhaseFlow(
|
||||
func, plane,
|
||||
run_time = 5,
|
||||
virtual_time = 8
|
||||
))
|
||||
|
||||
|
||||
|
||||
class TimeLine(Scene):
|
||||
def construct(self):
|
||||
dated_events = [
|
||||
{
|
||||
"date" : 1696,
|
||||
"text": "Johann Bernoulli poses Brachistochrone problem",
|
||||
"picture" : "Johann_Bernoulli2"
|
||||
},
|
||||
{
|
||||
"date" : 1662,
|
||||
"text" : "Fermat states his principle of least time",
|
||||
"picture" : "Pierre_de_Fermat"
|
||||
}
|
||||
]
|
||||
speical_dates = [2016] + [
|
||||
obj["date"] for obj in dated_events
|
||||
]
|
||||
centuries = list(range(1600, 2100, 100))
|
||||
timeline = NumberLine(
|
||||
numerical_radius = 300,
|
||||
number_at_center = 1800,
|
||||
unit_length_to_spatial_width = FRAME_X_RADIUS/100,
|
||||
tick_frequency = 10,
|
||||
numbers_with_elongated_ticks = centuries
|
||||
)
|
||||
timeline.add_numbers(*centuries)
|
||||
centers = [
|
||||
Point(timeline.number_to_point(year))
|
||||
for year in speical_dates
|
||||
]
|
||||
timeline.add(*centers)
|
||||
timeline.shift(-centers[0].get_center())
|
||||
|
||||
self.add(timeline)
|
||||
self.wait()
|
||||
run_times = iter([3, 1])
|
||||
for point, event in zip(centers[1:], dated_events):
|
||||
self.play(ApplyMethod(
|
||||
timeline.shift, -point.get_center(),
|
||||
run_time = next(run_times)
|
||||
))
|
||||
picture = ImageMobject(event["picture"], invert = False)
|
||||
picture.set_width(2)
|
||||
picture.to_corner(UP+RIGHT)
|
||||
event_mob = TextMobject(event["text"])
|
||||
event_mob.shift(2*LEFT+2*UP)
|
||||
date_mob = TexMobject(str(event["date"]))
|
||||
date_mob.scale(0.5)
|
||||
date_mob.shift(0.6*UP)
|
||||
line = Line(event_mob.get_bottom(), 0.2*UP)
|
||||
self.play(
|
||||
ShimmerIn(event_mob),
|
||||
ShowCreation(line),
|
||||
ShimmerIn(date_mob)
|
||||
)
|
||||
self.play(FadeIn(picture))
|
||||
self.wait(3)
|
||||
self.play(*list(map(FadeOut, [event_mob, date_mob, line, picture])))
|
||||
|
||||
|
||||
class StayedUpAllNight(Scene):
|
||||
def construct(self):
|
||||
clock = Circle(radius = 2, color = WHITE)
|
||||
clock.add(Dot(ORIGIN))
|
||||
ticks = Mobject(*[
|
||||
Line(1.8*vect, 2*vect, color = GREY)
|
||||
for vect in compass_directions(12)
|
||||
])
|
||||
clock.add(ticks)
|
||||
hour_hand = Line(ORIGIN, UP)
|
||||
minute_hand = Line(ORIGIN, 1.5*UP)
|
||||
clock.add(hour_hand, minute_hand)
|
||||
clock.to_corner(UP+RIGHT)
|
||||
hour_hand.get_center = lambda : clock.get_center()
|
||||
minute_hand.get_center = lambda : clock.get_center()
|
||||
|
||||
solution = ImageMobject(
|
||||
"Newton_brachistochrone_solution2",
|
||||
use_cache = False
|
||||
)
|
||||
solution.stroke_width = 3
|
||||
solution.set_color(GREY)
|
||||
solution.set_width(5)
|
||||
solution.to_corner(UP+RIGHT)
|
||||
newton = ImageMobject("Old_Newton", invert = False)
|
||||
newton.scale(0.8)
|
||||
phil_trans = TextMobject("Philosophical Transactions")
|
||||
rect = Rectangle(height = 6, width = 4.5, color = WHITE)
|
||||
rect.to_corner(UP+RIGHT)
|
||||
rect.shift(DOWN)
|
||||
phil_trans.set_width(0.8*rect.get_width())
|
||||
phil_trans.next_to(Point(rect.get_top()), DOWN)
|
||||
new_solution = solution.copy()
|
||||
new_solution.set_width(phil_trans.get_width())
|
||||
new_solution.next_to(phil_trans, DOWN, buff = 1)
|
||||
not_newton = TextMobject("-Totally not by Newton")
|
||||
not_newton.set_width(2.5)
|
||||
not_newton.next_to(new_solution, DOWN, aligned_edge = RIGHT)
|
||||
phil_trans.add(rect)
|
||||
|
||||
newton_complaint = TextMobject([
|
||||
"``I do not love to be",
|
||||
" \\emph{dunned} ",
|
||||
"and teased by foreigners''"
|
||||
], size = "\\small")
|
||||
newton_complaint.to_edge(UP, buff = 0.2)
|
||||
dunned = newton_complaint.split()[1]
|
||||
dunned.set_color()
|
||||
dunned_def = TextMobject("(old timey term for making \\\\ demands on someone)")
|
||||
dunned_def.scale(0.7)
|
||||
dunned_def.next_to(phil_trans, LEFT)
|
||||
dunned_def.shift(2*UP)
|
||||
dunned_arrow = Arrow(dunned_def, dunned)
|
||||
|
||||
johann = ImageMobject("Johann_Bernoulli2", invert = False)
|
||||
johann.scale(0.4)
|
||||
johann.to_edge(LEFT)
|
||||
johann.shift(DOWN)
|
||||
johann_quote = TextMobject("``I recognize the lion by his claw''")
|
||||
johann_quote.next_to(johann, UP, aligned_edge = LEFT)
|
||||
|
||||
self.play(ApplyMethod(newton.to_edge, LEFT))
|
||||
self.play(ShowCreation(clock))
|
||||
kwargs = {
|
||||
"axis" : OUT,
|
||||
"rate_func" : smooth
|
||||
}
|
||||
self.play(
|
||||
Rotating(hour_hand, radians = -2*np.pi, **kwargs),
|
||||
Rotating(minute_hand, radians = -12*2*np.pi, **kwargs),
|
||||
run_time = 5
|
||||
)
|
||||
self.wait()
|
||||
self.clear()
|
||||
self.add(newton)
|
||||
clock.ingest_submobjects()
|
||||
self.play(Transform(clock, solution))
|
||||
self.remove(clock)
|
||||
self.add(solution)
|
||||
self.wait()
|
||||
self.play(
|
||||
FadeIn(phil_trans),
|
||||
Transform(solution, new_solution)
|
||||
)
|
||||
self.wait()
|
||||
self.play(ShimmerIn(not_newton))
|
||||
phil_trans.add(solution, not_newton)
|
||||
self.wait()
|
||||
self.play(*list(map(ShimmerIn, newton_complaint.split())))
|
||||
self.wait()
|
||||
self.play(
|
||||
ShimmerIn(dunned_def),
|
||||
ShowCreation(dunned_arrow)
|
||||
)
|
||||
self.wait()
|
||||
self.remove(dunned_def, dunned_arrow)
|
||||
self.play(FadeOut(newton_complaint))
|
||||
self.remove(newton_complaint)
|
||||
self.play(
|
||||
FadeOut(newton),
|
||||
GrowFromCenter(johann)
|
||||
)
|
||||
self.remove(newton)
|
||||
self.wait()
|
||||
self.play(ShimmerIn(johann_quote))
|
||||
self.wait()
|
||||
|
||||
|
||||
class ThetaTGraph(Scene):
|
||||
def construct(self):
|
||||
t_axis = NumberLine()
|
||||
theta_axis = NumberLine().rotate(np.pi/2)
|
||||
theta_mob = TexMobject("\\theta(t)")
|
||||
t_mob = TexMobject("t")
|
||||
theta_mob.next_to(theta_axis, RIGHT)
|
||||
theta_mob.to_edge(UP)
|
||||
t_mob.next_to(t_axis, UP)
|
||||
t_mob.to_edge(RIGHT)
|
||||
graph = ParametricFunction(
|
||||
lambda t : 4*t*RIGHT + 2*smooth(t)*UP
|
||||
)
|
||||
line = Line(graph.points[0], graph.points[-1], color = WHITE)
|
||||
q_mark = TextMobject("?")
|
||||
q_mark.next_to(Point(graph.get_center()), LEFT)
|
||||
stars = Stars(color = BLACK)
|
||||
stars.scale(0.1).shift(q_mark.get_center())
|
||||
|
||||
|
||||
squiggle = ParametricFunction(
|
||||
lambda t : t*RIGHT + 0.2*t*(5-t)*(np.sin(t)**2)*UP,
|
||||
start = 0,
|
||||
end = 5
|
||||
)
|
||||
|
||||
self.play(
|
||||
ShowCreation(t_axis),
|
||||
ShowCreation(theta_axis),
|
||||
ShimmerIn(theta_mob),
|
||||
ShimmerIn(t_mob)
|
||||
)
|
||||
self.play(
|
||||
ShimmerIn(q_mark),
|
||||
ShowCreation(graph)
|
||||
)
|
||||
self.wait()
|
||||
self.play(
|
||||
Transform(q_mark, stars),
|
||||
Transform(graph, line)
|
||||
)
|
||||
self.wait()
|
||||
self.play(Transform(graph, squiggle))
|
||||
self.wait()
|
||||
|
||||
|
||||
class SolutionsToTheBrachistochrone(Scene):
|
||||
def construct(self):
|
||||
r_range = np.arange(0.5, 2, 0.25)
|
||||
cycloids = Mobject(*[
|
||||
Cycloid(radius = r, end_theta=2*np.pi)
|
||||
for r in r_range
|
||||
])
|
||||
lower_left = 2*DOWN+6*LEFT
|
||||
lines = Mobject(*[
|
||||
Line(
|
||||
lower_left,
|
||||
lower_left+5*r*np.cos(np.arctan(r))*RIGHT+2*r*np.sin(np.arctan(r))*UP
|
||||
)
|
||||
for r in r_range
|
||||
])
|
||||
nl = NumberLine(numbers_with_elongated_ticks = [])
|
||||
x_axis = nl.copy().shift(3*UP)
|
||||
y_axis = nl.copy().rotate(np.pi/2).shift(6*LEFT)
|
||||
t_axis = nl.copy().shift(2*DOWN)
|
||||
x_label = TexMobject("x")
|
||||
x_label.next_to(x_axis, DOWN)
|
||||
x_label.to_edge(RIGHT)
|
||||
y_label = TexMobject("y")
|
||||
y_label.next_to(y_axis, RIGHT)
|
||||
y_label.shift(2*DOWN)
|
||||
t_label = TexMobject("t")
|
||||
t_label.next_to(t_axis, UP)
|
||||
t_label.to_edge(RIGHT)
|
||||
theta_label = TexMobject("\\theta")
|
||||
theta_label.next_to(y_axis, RIGHT)
|
||||
theta_label.to_edge(UP)
|
||||
words = TextMobject("Boundary conditions?")
|
||||
words.next_to(lines, RIGHT)
|
||||
words.shift(2*UP)
|
||||
|
||||
self.play(ShowCreation(x_axis), ShimmerIn(x_label))
|
||||
self.play(ShowCreation(y_axis), ShimmerIn(y_label))
|
||||
self.play(ShowCreation(cycloids))
|
||||
self.wait()
|
||||
self.play(
|
||||
Transform(cycloids, lines),
|
||||
Transform(x_axis, t_axis),
|
||||
Transform(x_label, t_label),
|
||||
Transform(y_label, theta_label),
|
||||
run_time = 2
|
||||
)
|
||||
self.wait()
|
||||
self.play(ShimmerIn(words))
|
||||
self.wait()
|
||||
|
||||
|
||||
class VideoLayout(Scene):
|
||||
def construct(self):
|
||||
left, right = 5*LEFT, 5*RIGHT
|
||||
top_words = TextMobject("The next 15 minutes of your life:")
|
||||
top_words.to_edge(UP)
|
||||
line = Line(left, right, color = BLUE_D)
|
||||
for a in np.arange(0, 4./3, 1./3):
|
||||
vect = interpolate(left, right, a)
|
||||
line.add_line(vect+0.2*DOWN, vect+0.2*UP)
|
||||
left_brace = Brace(
|
||||
Mobject(
|
||||
Point(left),
|
||||
Point(interpolate(left, right, 2./3))
|
||||
),
|
||||
DOWN
|
||||
)
|
||||
right_brace = Brace(
|
||||
Mobject(
|
||||
Point(interpolate(left, right, 2./3)),
|
||||
Point(right)
|
||||
),
|
||||
UP
|
||||
)
|
||||
left_brace.words = list(map(TextMobject, [
|
||||
"Problem statement",
|
||||
"History",
|
||||
"Johann Bernoulli's cleverness"
|
||||
]))
|
||||
curr = left_brace
|
||||
right_brace.words = list(map(TextMobject, [
|
||||
"Challenge",
|
||||
"Mark Levi's cleverness",
|
||||
]))
|
||||
for brace in left_brace, right_brace:
|
||||
curr = brace
|
||||
direction = DOWN if brace is left_brace else UP
|
||||
for word in brace.words:
|
||||
word.next_to(curr, direction)
|
||||
curr = word
|
||||
right_brace.words.reverse()
|
||||
|
||||
self.play(ShimmerIn(top_words))
|
||||
self.play(ShowCreation(line))
|
||||
for brace in left_brace, right_brace:
|
||||
self.play(GrowFromCenter(brace))
|
||||
self.wait()
|
||||
for word in brace.words:
|
||||
self.play(ShimmerIn(word))
|
||||
self.wait()
|
||||
|
||||
|
||||
|
||||
|
||||
class ShortestPathProblem(Scene):
|
||||
def construct(self):
|
||||
point_a, point_b = 3*LEFT, 3*RIGHT
|
||||
dots = []
|
||||
for point, char in [(point_a, "A"), (point_b, "B")]:
|
||||
dot = Dot(point)
|
||||
letter = TexMobject(char)
|
||||
letter.next_to(dot, UP+LEFT)
|
||||
dot.add(letter)
|
||||
dots.append(dot)
|
||||
|
||||
path = ParametricFunction(
|
||||
lambda t : (t/2 + np.cos(t))*RIGHT + np.sin(t)*UP,
|
||||
start = -2*np.pi,
|
||||
end = 2*np.pi
|
||||
)
|
||||
path.scale(6/(2*np.pi))
|
||||
path.shift(point_a - path.points[0])
|
||||
path.set_color(RED)
|
||||
line = Line(point_a, point_b)
|
||||
words = TextMobject("Shortest path from $A$ to $B$")
|
||||
words.to_edge(UP)
|
||||
|
||||
self.play(
|
||||
ShimmerIn(words),
|
||||
*list(map(GrowFromCenter, dots))
|
||||
)
|
||||
self.play(ShowCreation(path))
|
||||
self.play(Transform(
|
||||
path, line,
|
||||
path_func = path_along_arc(np.pi)
|
||||
))
|
||||
self.wait()
|
||||
|
||||
|
||||
class MathBetterThanTalking(Scene):
|
||||
def construct(self):
|
||||
mathy = Mathematician()
|
||||
mathy.to_corner(DOWN+LEFT)
|
||||
bubble = ThoughtBubble()
|
||||
bubble.pin_to(mathy)
|
||||
bubble.write("Math $>$ Talking about math")
|
||||
|
||||
self.add(mathy)
|
||||
self.play(ShowCreation(bubble))
|
||||
self.play(ShimmerIn(bubble.content))
|
||||
self.wait()
|
||||
self.play(ApplyMethod(
|
||||
mathy.blink,
|
||||
rate_func = squish_rate_func(there_and_back, 0.4, 0.6)
|
||||
))
|
||||
|
||||
|
||||
class DetailsOfProofBox(Scene):
|
||||
def construct(self):
|
||||
rect = Rectangle(height = 4, width = 6, color = WHITE)
|
||||
words = TextMobject("Details of proof")
|
||||
words.to_edge(UP)
|
||||
|
||||
self.play(
|
||||
ShowCreation(rect),
|
||||
ShimmerIn(words)
|
||||
)
|
||||
self.wait()
|
||||
|
||||
|
||||
|
||||
class TalkedAboutSnellsLaw(Scene):
|
||||
def construct(self):
|
||||
randy = Randolph()
|
||||
randy.to_corner(DOWN+LEFT)
|
||||
morty = Mortimer()
|
||||
morty.to_edge(DOWN+RIGHT)
|
||||
randy.bubble = SpeechBubble().pin_to(randy)
|
||||
morty.bubble = SpeechBubble().pin_to(morty)
|
||||
|
||||
phrases = [
|
||||
"Let's talk about Snell's law",
|
||||
"I love Snell's law",
|
||||
"It's like running from \\\\ a beach into the ocean",
|
||||
"It's like two constant \\\\ tension springs",
|
||||
]
|
||||
|
||||
self.add(randy, morty)
|
||||
talkers = it.cycle([randy, morty])
|
||||
for talker, phrase in zip(talkers, phrases):
|
||||
talker.bubble.write(phrase)
|
||||
self.play(
|
||||
FadeIn(talker.bubble),
|
||||
ShimmerIn(talker.bubble.content)
|
||||
)
|
||||
self.play(ApplyMethod(
|
||||
talker.blink,
|
||||
rate_func = squish_rate_func(there_and_back)
|
||||
))
|
||||
self.wait()
|
||||
self.remove(talker.bubble, talker.bubble.content)
|
||||
|
||||
|
||||
class YetAnotherMarkLevi(Scene):
|
||||
def construct(self):
|
||||
words = TextMobject("Yet another bit of Mark Levi cleverness")
|
||||
words.to_edge(UP)
|
||||
levi = ImageMobject("Mark_Levi", invert = False)
|
||||
levi.set_width(6)
|
||||
levi.show()
|
||||
|
||||
self.add(levi)
|
||||
self.play(ShimmerIn(words))
|
||||
self.wait(2)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user