LoginSignup
0
1

More than 1 year has passed since last update.

manimの作法 その60

Last updated at Posted at 2021-06-10

概要

manimの作法、調べてみた。
add_updater、使ってみた。

サンプルコード

from manimlib.imports import *

def temperature_to_color(temp, min_temp = -1, max_temp = 1):
    colors = [BLUE, TEAL, GREEN, YELLOW, "#ff0000"]
    alpha = inverse_interpolate(min_temp, max_temp, temp)
    index, sub_alpha = integer_interpolate(0, len(colors) - 1, alpha)
    return interpolate_color(colors[index], colors[index + 1], sub_alpha)

def two_d_temp_func(x, y, t):
    return np.sum([c * np.sin(f * var) * np.exp(-(f ** 2) * t) for c, f, var in [(0.2, 1, x), (0.3, 3, x), (0.02, 5, x), (0.01, 7, x), (0.5, 2, y), (0.1, 10, y), (0.01, 20, y), ]])

class test(ThreeDScene):
    CONFIG = {
        "cells_per_side": 20,
        "body_height": 6,
    }
    def construct(self):
        self.introduce_body()
        self.show_temperature_at_all_points()
    def introduce_body(self):
        height = self.body_height
        buff = 0.025
        rows = VGroup(*[VGroup(*[Dot(stroke_width = 0, fill_opacity = 1, ) for x in range(self.cells_per_side)]).arrange(RIGHT, buff = buff) for y in range(self.cells_per_side)]).arrange(DOWN, buff=buff)
        for row in rows[1::2]:
            row.submobjects.reverse()
        body = self.body = VGroup(*it.chain(*rows))
        body.set_height(height)
        body.center()
        body.to_edge(LEFT)
        axes = self.axes = Axes(x_min = -5, x_max = 5, y_min = -5, y_max = 5, )
        axes.match_height(body)
        axes.move_to(body)
        for cell in body:
            self.color_cell(cell)
        plate = Square(stroke_width = 0, fill_color = DARK_GREY, sheen_direction = UL, sheen_factor = 1, fill_opacity = 1, )
        plate.replace(body)
        plate_words = TextMobject("Piece of \\\\ metal")
        plate_words.scale(2)
        plate_words.set_stroke(BLACK, 2, background = True)
        plate_words.set_color(BLACK)
        plate_words.move_to(plate)
        self.play(DrawBorderThenFill(plate), Write(plate_words, run_time = 2, rate_func = squish_rate_func(smooth, 0.5, 1)))
        self.wait()
        self.remove(plate_words)
    def show_temperature_at_all_points(self):
        body = self.body
        start_corner = body[0].get_center()
        dot = Dot(radius = 0.01, color = WHITE)
        dot.move_to(start_corner)
        get_point = dot.get_center
        lhs = TexMobject("T = ")
        lhs.next_to(body, RIGHT, LARGE_BUFF)
        decimal = DecimalNumber(num_decimal_places = 1, unit = "^\\circ")
        decimal.next_to(lhs, RIGHT, MED_SMALL_BUFF, DOWN)
        decimal.add_updater(lambda d: d.set_value(40 + 50 * self.point_to_temp(get_point())))
        arrow = Arrow(color = YELLOW)
        arrow.set_stroke(BLACK, 8, background = True)
        arrow.tip.set_stroke(BLACK, 2, background = True)
        arrow.add_updater(lambda a: a.put_start_and_end_on(lhs.get_left() + MED_SMALL_BUFF * LEFT, get_point(), ))
        dot.add_updater(lambda p: p.move_to(body[-1] if (1 < len(body)) else start_corner))
        self.add(body, dot, lhs, decimal, arrow)
        self.play(ShowIncreasingSubsets(body, run_time = 10, rate_func = linear, ))
        self.wait()
        self.remove(dot)
        self.play(FadeOut(arrow), FadeOut(lhs), FadeOut(decimal), )
    def point_to_temp(self, point, time = 0):
        x, y = self.axes.point_to_coords(point)
        return two_d_temp_func(0.3 * x, 0.3 * y, t = time)
    def color_cell(self, cell, vect = RIGHT):
        p0 = cell.get_corner(-vect)
        p1 = cell.get_corner(vect)
        colors = []
        for point in p0, p1:
            temp = self.point_to_temp(point)
            color = temperature_to_color(temp)
            colors.append(color)
        cell.set_color(color = colors)
        cell.set_sheen_direction(vect)
        return cell





生成した動画

以上。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1