انیمیشن‌های 3Blue1Brown چطور ساخته می‌شن؟

هادی.

کاربر فعال
کنکوری 1405
ارسال‌ها
66
امتیاز
621
نام مرکز سمپاد
شهیدبهشتی
شهر
بوشهر
سال فارغ التحصیلی
1405
جواب کوتاه: با پایتون! (درواقع Manim)

احتمالا اگر کمی تو یوتیوب گشته باشید و محتوای حول‌محور ریاضیات، فیزیک و علوم کامپیوتر رو دنبال کرده باشید، یکی از کانال‌هایی که خیلی به چشمتون خواهد خورد، کانال 3Blue1Brown هست که بخاطر صدای شیوای گوینده و انیمیشن‌های کامل، علمی و جالبش خیلی معروف شده. برای شناخت بیشتر خوبه بدونید که این کانال رو آقای Grant Sanderson، فارغ‌التحصیل لیسانس از دانشگاه استنفورد ساخته و می‌گردونه و پیش‌زمینه آموزشش برمی‌گرده به سال ۲۰۱۵ و زمانی که با خان آکادمی کار می‌کرده.

8b2801_25Screenshot-From-2025-06-30-21-07-58.png

اینا موضوعاتی هستن که این کانال تاحالا بهش پرداخته.​

انیمیشن‌های این کانال با استفاده از یک موتور انیمیشن‌سازی اختصاصی به اسم Manim(مخفف Math Animation) ساخته می‌شن. این موتور با پایتون و توسط همین آقای ساندرسون در همون سال فارغ‌التحصیلی که ۲۰۱۵ هست ساخته شده. درحال حاضر هم دو نسخه از این موتور وجود داره در دو مخزن گیت‌هاب مختلف، یکی که خودش توسعه می‌ده و کاراش رو انجام می‌ده و یکی هم که جامعه‌محور هست و آدم‌های علاقه‌مند و پیگیر پشتیبانی می‌کنن ازش و بهبودش می‌دن. ما اینجا از نسخه جامعه استفاده خواهیم کرد چون مستندات بهتری داره. حالا این انیمیشن‌ها رو می‌شه به صورت‌های مختلف خروجی گرفت و ازشون استفاده کرد، در ارائه، ویدیوهای یوتیوب و حتی آموزش توی یک کلاس.

خب برای استفاده ازش اول لازمه که پایتون رو نصب کنید،‌ بعدش هم manim رو و البته یک نسخه آنلاین هم دارند و نیاز به این دردسرهای نصب به صورت local نداره. (لینک رو که باز کنید براتون یک Jupyter Notebook می‌سازه تا بتونید کاراتون رو انجام بدید داخلش. راهنما هم داره.) https://try.manim.community

مرحله بعد استفاده کردن ازشه،‌ مثلا خودشون توی مثال‌هایی که دارن این رو نشون می‌دن: یک دایره آبی که تبدیل می‌شه به یک مربع سبز. چطور می‌سازیم؟ با این کد:

Python:
import manim as mn
from manim import *

config.media_width = "75%"
config.verbosity = "WARNING"

class CircleToSquare(Scene):
    def construct(self):
        blue_circle = Circle(color=BLUE, fill_opacity=0.5)
        green_square = Square(color=GREEN, fill_opacity=0.8)
        self.play(Create(blue_circle))
        self.wait()

        self.play(Transform(blue_circle, green_square))
        self.wait()
‌ استفاده ازش هم ساده‌ست اگر کمی پایتون بلد باشید. یک کلاس می‌سازید که از کلاس Scene ارث‌بری کرده و می‌شه پرده شما. هر کلاسی که از این Scene ارث‌بری کرده باشه می‌شه یک پرده جدا. و صد البته شما می‌تونید پرده‌ها رو باهم ترکیب کنید. دو متغیر برای تعریف اشکال، در نهایت تابع play برای کشیدنشون و در آخر هم Transform برای تبدیل.
و با این دستور هم خروجی رو می‌گیریم:
Bash:
manim -qm main.py CircleToSquare
من خروجی گیف می‌گیرم تا بتونم اینجا بهتر نمایشش بدم:
Bash:
manim -qm --format=gif main.py CircleToSquare

7b0d01_25CircleToSquare-ManimCE-v0-18-1.gif


این یک پروژه خیلی ساده‌ست، شما می‌تونید با یه ذره زحمت بیشتر بیاید و یک قضیه رو اثبات کنید، مثلا قضیه فیثاغورث. (یا از هوش مصنوعی کمک بگیرید!‌ و کد رو کپی‌پیست کنید و خروجی بگیرید ازش. البته بنا به دلایلی باید ویرایش‌های نسبتا زیادی انجام بدید تا به نتیجه دلخواه برسید.) خب برای اثبات قضیه فیثاغورث شما به همچین کدی نیاز دارید:

Python:
from manim import *
import numpy as np

class PythagoreanSimilarityProof(Scene):
    def construct(self):

        A = np.array([0, 2, 0])
        B = np.array([-5, -1, 0])
        C = np.array([2, -1, 0])

        triangle_ABC = Polygon(A, B, C, color=BLUE, fill_opacity=0.2)

        label_A = MathTex("A").next_to(A, UP)
        label_B = MathTex("B").next_to(B, DOWN)
        label_C = MathTex("C").next_to(C, DOWN)

        self.play(Create(triangle_ABC))
        self.play(Write(label_A), Write(label_B), Write(label_C))
        self.wait(1)

        right_angle_marker = RightAngle(Line(A, B), Line(A, C), length=0.3, quadrant=(1, 1))
        self.play(Create(right_angle_marker))

        side_a = MathTex("a").move_to((B + C) / 2 + DOWN * 0.4)
        side_b = MathTex("b").move_to((A + C) / 2 + RIGHT * 0.4)
        side_c = MathTex("c").move_to((A + B) / 2 + LEFT * 0.4)

        self.play(Write(side_a), Write(side_b), Write(side_c))
        self.wait(2)

        BC_vector = C - B
        BA_vector = A - B
        t = np.dot(BA_vector, BC_vector) / np.dot(BC_vector, BC_vector)
        H = B + t * BC_vector

        altitude = DashedLine(A, H, color=RED)
        label_H = MathTex("H").next_to(H, DOWN)

        self.play(Create(altitude), Write(label_H))
        self.wait(2)

        triangle_ABH = Polygon(A, B, H, color=GREEN, fill_opacity=0.3)
        self.play(Create(triangle_ABH))
        self.wait(1)

        triangle_ACH = Polygon(A, C, H, color=YELLOW, fill_opacity=0.3)
        self.play(Create(triangle_ACH))
        self.wait(1)

        self.play(triangle_ABH.animate.set_fill_opacity(0.1),
                  triangle_ACH.animate.set_fill_opacity(0.1))
        self.wait(1)


        all_objects = VGroup(triangle_ABC, triangle_ABH, triangle_ACH, altitude,
                           label_A, label_B, label_C, label_H,
                           side_a, side_b, side_c, right_angle_marker)
        self.play(all_objects.animate.shift(UP * 1.2).scale(0.8))

        similarity1 = MathTex(r"\triangle ABH \sim \triangle ABC")
        similarity2 = MathTex(r"\triangle ACH \sim \triangle ABC")

        similarity1.move_to(DOWN * 2)
        similarity2.next_to(similarity1, DOWN)

        self.play(Write(similarity1))
        self.wait(1)
        self.play(Write(similarity2))
        self.wait(2)

        self.play(FadeOut(similarity1), FadeOut(similarity2))

        proportion1 = MathTex(r"\frac{AB}{BC} = \frac{BH}{AB} \Rightarrow AB^2 = BH \cdot BC")
        proportion2 = MathTex(r"\frac{AC}{HC} = \frac{BC}{AC} \Rightarrow AC^2 = BC \cdot HC")

        proportion1.move_to(DOWN * 2).scale(0.8)
        proportion2.next_to(proportion1, DOWN).scale(0.8)

        self.play(Write(proportion1))
        self.wait(2)
        self.play(Write(proportion2))
        self.wait(2)

        self.play(FadeOut(proportion1), FadeOut(proportion2))

        pythagorean1 = MathTex(r"AB^2 + AC^2 = BH \cdot BC + BC \cdot HC")
        pythagorean2 = MathTex(r"AB^2 + AC^2 = BC \cdot (BH + CH)")
        pythagorean3 = MathTex(r"AB^2 + AC^2 = BC \cdot BC")
        pythagorean4 = MathTex(r"AB^2 + AC^2 = BC^2")
        pythagorean5 = MathTex(r"b^2 + c^2 = a^2")

        equations = VGroup(pythagorean1, pythagorean2, pythagorean3, pythagorean4, pythagorean5)
        equations.arrange(DOWN, buff=0.3)
        equations.move_to(DOWN * 2).scale(0.7)

        self.play(Write(pythagorean1))
        self.wait(2)
        self.play(Transform(pythagorean1, pythagorean2))
        self.wait(2)
        self.play(Transform(pythagorean1, pythagorean3))
        self.wait(2)
        self.play(Transform(pythagorean1, pythagorean4))
        self.wait(2)
        self.play(Transform(pythagorean1, pythagorean5))
        self.wait(2)

        self.play(FadeOut(pythagorean1))

        conclusion = Text("Therefore: a² = b² + c²", font_size=28, color=RED)
        conclusion.move_to(DOWN * 3.5)
        self.play(Write(conclusion))

        self.wait(3)
از تابع play برای پخش کردن هر شکلی که می‌کشیم استفاده می‌کنیم. و برای کشیدنشون هم از Write استفاده می‌کنیم. یک مثلث قائم‌الزاویه می‌سازیم، نام‌گذاریش می‌کنیم، بر وتر خطی رو عمود می‌کنیم و با استفاده از MathTex شروع به نوشتن روابط ریاضی لازم برای اثباتش می‌کنیم.
و با استفاده از همون دستور قبلی خروجی رو می‌گیریم: (چون اسم پرده تغییر کرده پس ما هم تغییر می‌دیم و از -pql استفاده می‌کنیم تا خروجی رو در یک پلیر ویدیو باز کنه.)

Bash:
manim -pql main.py PythagoreanSimilarityProof
917901_25PythagoreanSimilarityProof-ManimCE-v0-18-1.gif


خب این تا اینجا،‌ شما تونستید یک ویدیو نسبتا ساده رو بسازید. برای ویدیوهای پیچید‌ه‌تر لازمه که کدهای بقیه رو بخونید تا دستتون بیاد که چطور مثلا 3b1b تونسته همچین چیزایی رو خلق کنه. (از اینجا می‌تونید کدهای تمام ویدیوهای این مدت این کانال رو ببینید).
نکته جالب هم اینکه چون می‌تونید از Tex استفاده کنید توی manim پس متن فارسی هم می‌تونید رندر بگیرید یا حتی باهاش ساختارهای مولکول‌ها رو نشون بدید. کلی هم پلاگین مختلف وجود داره که می‌تونید ازشون استفاده کنید:
https://plugins.manim.community
خلاصه که دستتون برای کارهای مختلف بازه. باقی کار رو می‌سپارم به خودتون و سرچ‌هایی که قراره انجام بدید اگر علاقه‌مند بودید. دیدن این ویدیو هم از خود کانال 3b1b برای آموزش استفاده ازش خالی از لطف نیست.
 
Back
بالا