manimの作法 その60

#概要

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





```

#生成した動画

https://www.youtube.com/watch?v=hhQae5KETd8

以上。