【manim】之圓規動畫

来源:https://www.cnblogs.com/wang_yb/archive/2023/01/31/17079903.html
-Advertisement-
Play Games

概要 前端時間做尺規作圖相關的動畫的時候,封裝了一個圓規的動畫,順便研究了下 manim 庫的動畫函數。 manim 本身就是做動畫的庫,所以,基於它封裝自定義的動畫非常方便。 動畫原理 對於單個的元素,manim本身就提供了非常多的動畫函數。 比如:創建/消除的動畫,移動元素的動畫,旋轉元素的動畫 ...


概要

前端時間做尺規作圖相關的動畫的時候,封裝了一個圓規的動畫,順便研究了下 manim 庫的動畫函數。

manim 本身就是做動畫的庫,所以,基於它封裝自定義的動畫非常方便。

動畫原理

對於單個的元素,manim本身就提供了非常多的動畫函數。
比如:創建/消除的動畫,移動元素的動畫,旋轉元素的動畫等等,具體可以參考: Animations

如果是做一些簡單的演示視頻的話,這些內置的動畫函數滿足要求綽綽有餘。
但是,對於多個元素聯動的動畫,則需要編寫各個元素之間的聯動規則,來封裝符合要求的動畫。

下麵以圓規動畫為例,演示多元素動畫如何封裝。

圓規動畫目的還是畫出一個 圓弧,只是在繪製的圓弧的過程中展示了圓弧的起點,終點以及連接起點終點之間的線。
這樣,實際使用圓規作圖的時候,可以更好的理解 圓弧是如何畫出來的。

函數的簽名如下:


def ruler(sc: Scene, p1, p2, angle=PI, axis=OUT):
    """
    圓規動畫


    Parameters
    ---------
    sc
        繪製動畫的場景
    p1
        代表圓規的針,繪製時不動的點
    p2
        代表圓規的筆芯,繪製圓弧的點
    angle
        繪製圓弧的角度,預設PI,相當於繪製半個圓
    axis
        只有2個值 IN/OUT,分別表示順時針還是逆時針作弧
    """
    # 省略。。。
    return arc

各個參數的含義參見註釋。

實現動畫的思路如下:

  1. 構建3個元素,也就是d1(根據參數中p1坐標繪製的點),d2(根據參數中p2坐標繪製的點)以及 dl(連接p1和p2的虛線)
  2. 設置dl的動畫,隨著 d1d2變化不斷重新繪製(這裡 d1其實是不會變的)
  3. 再設置圓弧的動畫,隨著 d2的變動,不斷繪製新的圓弧
  4. 通過 manim自帶的動畫函數讓 d2先動,其他動畫則會隨之一起
  5. 最後刪除不必要的元素,只保留圓弧在 場景(sc)中
def ruler(sc: Scene, p1, p2, angle=PI, axis=OUT):
    """
    圓規動畫


    Parameters
    ---------
    sc
        繪製動畫的場景
    p1
        代表圓規的針,繪製時不動的點
    p2
        代表圓規的筆芯,繪製圓弧的點
    angle
        繪製圓弧的角度,預設PI,相當於繪製半個圓
    axis
        只有2個值 IN/OUT,分別表示順時針還是逆時針作弧
    """
    d1 = Dot(point=p1, color=RED)
    d2 = Dot(point=p2, color=GREEN)
    dl = DashedLine(d1.get_center(), d2.get_center())

    r = np.linalg.norm(p2 - p1)
    arc = ArcBetweenPoints(p2, p2)

    dl.add_updater(lambda z: z.become(DashedLine(d1.get_center(), d2.get_center())))
    if np.array_equal(axis, OUT):
        arc.add_updater(
            lambda z: z.become(
                ArcBetweenPoints(p2, d2.get_center(), radius=r, stroke_color=GREEN)
            )
        )
    if np.array_equal(axis, IN):
        arc.add_updater(
            lambda z: z.become(
                ArcBetweenPoints(d2.get_center(), p2, radius=r, stroke_color=GREEN)
            )
        )

    sc.add(d1, d2, dl, arc)
    sc.play(
        Rotate(
            d2,
            about_point=d1.get_center(),
            axis=axis,
            angle=angle,
            rate_func=linear,
        )
    )

    arc.clear_updaters()
    dl.clear_updaters()
    sc.remove(d1, d2, dl)
    return arc

動畫效果

封裝之後,使用起來非常簡單:

# -*- coding: utf-8 -*-
from manim import *
import numpy as np


class Sample(Scene):
    def construct(self):
        ruler(self, np.array([-1, 0, 0]), np.array([-1, 1, 0]))
        ruler(self, np.array([1, 0, 0]), np.array([1, 1, 0]), axis=IN)
        self.wait()

上面演示了逆時針(預設是逆時針)和順時針方式繪製半圓。
out.gif

各個元素的顏色等相關屬性,沒有暴露到函數參數中,可以直接在代碼中修改。
這裡主要演示如何基於 manim製作多元素動畫的。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 簡單介紹一下Go中Gin使用get和post方法獲取前端數據 1.使用get方法獲取url中的參數 因為我使用的網頁只需要在url上傳一個參數,簡單介紹一下,get方法的傳參吧,可能不全,後續補充~ 在主函數使用get/post方式載入需要從網頁中使用get/post方法獲取數據如下(預設使用get ...
  • 聲明:文章僅用於學習交流,切勿用於非法用途。 一、autojs版本 使用autojs版本4.1,其餘版本對微信、qq、抖音有限制。 下載地址:關註【產品經理不是經理】gzh,回覆【autojs】即可下載。 官方文檔:https://pro.autojs.org/docs/zh/v8/ 學習要點:熟悉 ...
  • 一、 為什麼要多線程 CPU和IO設備之間的速度存在很大的差異,提高CPU利用率 提高服務端併發量 線程安全問題: 有共用數據的情況下使用多線程可能會導致線程安全問題 原子性:時間片輪轉導致 可見性:CPU和記憶體之間有緩存/工作記憶體和主記憶體 有序性:指令重排序 實現線程安全的方法: 互斥同步:悲觀 ...
  • 程式設計基礎 基礎知識 什麼是程式? 為進行某項活動的步驟,電腦的程式,為得到某種結果,通過電腦語言表達的指令序列。 什麼是程式設計? 計算思維,是運用電腦科學的基礎概念進行問題求解,系統設計,以及人類行為理解等涵蓋電腦科學之廣度的一系列思維活動。 計算思維的特點: 1.滿足電腦程式執行的 ...
  • Gin框架實戰——HTML渲染 最近使用Go的Gin框架做了個簡單的前端網頁,記錄一下細節~ 1.載入靜態文件 由於網頁需要使用css、圖片等渲染,而靜態文件必須先聲明:否則模板中調用載入不出來,這個很重要,即使你把文件放到對應路徑下,html中也寫了相應的路徑,但是開啟go服務端的網頁,會顯示不出 ...
  • 1、shutil高級文件操作模塊 shutil模塊提供了大量的文件的高級操作。特別針對文件拷貝和刪除,主要功能為目錄和文件操作以及壓縮操作。對單個文件的操作也可參見os模塊。 2、shutil模塊的拷貝方法 >>> import shutil >>> shutil.chown('test.txt', ...
  • 一、DDS工作原理 以正弦信號為例,DDS大概就是將M個點的一個周期的正弦序列存入ROM中,序列數據的地址就是正弦信號的相位; 通過修改頻率控制字(Fword)來改變每隔多少個地址取ROM里的數據進行輸出。頻率控制字越大,從ROM取出的數據點就越少,點數越少,輸出一個周期信號的時間就越短,從而改變了 ...
  • 在做SpringBoot項目的過程中,有時客戶會提出按照指定時間執行一次業務的需求。 在單一使用ScheduledTaskRegistrar類解決定時任務問題的時候,可能會達不到預期的動態調整定時任務的效果。 ...
一周排行
    -Advertisement-
    Play Games
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...