Skip to content

Instantly share code, notes, and snippets.

@thomasahle
Created September 10, 2024 16:41
Show Gist options
  • Save thomasahle/03a3e74d6a0637229ae515d69928eb1d to your computer and use it in GitHub Desktop.
Save thomasahle/03a3e74d6a0637229ae515d69928eb1d to your computer and use it in GitHub Desktop.
from manim import *
import numpy as np
class DualRingHeatTransferAnimation(Scene):
def construct(self):
# Configuration
num_blocks = 20
num_around = 39
block_size = 0.4
outer_radius = 3.3
inner_radius = 2.9
step_time = 0.3
pause_time = 0.1
color_change_time = 0.4
num_steps = 2 * num_around
num_steps = 13
step_angle = TAU / num_around
# Create outer and inner rings of blocks
outer_blocks = VGroup(*[Square(side_length=block_size, stroke_width=1) for _ in range(num_blocks)])
inner_blocks = VGroup(*[Square(side_length=block_size, stroke_width=1) for _ in range(num_blocks)])
# Position blocks in circles
def position_blocks(blocks, radius, sign=1, start_angle=0):
for i, block in enumerate(blocks):
angle = i * step_angle * sign + start_angle
block.move_to([radius, 0, 0])
block.rotate(angle, about_point=ORIGIN)
position_blocks(outer_blocks, outer_radius, -1)
position_blocks(inner_blocks, inner_radius, +1, step_angle)
# Set initial temperatures and colors
outer_temps = [1.0] * num_blocks
inner_temps = [0.0] * num_blocks
def get_color(temp):
return color_gradient((BLACK, RED), 101)[int(temp * 100)]
def update_colors(blocks, temps):
for block, temp in zip(blocks, temps):
block.set_fill(color=get_color(temp), opacity=1)
update_colors(outer_blocks, outer_temps)
update_colors(inner_blocks, inner_temps)
# Add blocks to the scene
self.add(outer_blocks, inner_blocks)
# Animate the movement and heat transfer
for offset in range(num_steps):
# Move rings
move_animations = [
outer_blocks.animate.rotate(step_angle/2, about_point=ORIGIN),
inner_blocks.animate.rotate(-step_angle/2, about_point=ORIGIN),
]
self.play(*move_animations, run_time=step_time)
# Pause movement
self.wait(pause_time)
# Perform heat transfer and prepare color change animations
color_animations = []
for i in range(num_blocks):
outer_index = i % num_around
inner_index = (offset - i) % num_around
if inner_index >= num_blocks or outer_index >= num_blocks:
continue
avg_temp = (outer_temps[outer_index] + inner_temps[inner_index]) / 2
outer_temps[outer_index] = avg_temp
inner_temps[inner_index] = avg_temp
color_animations += [
outer_blocks[outer_index].animate.set_fill(color=get_color(avg_temp)),
inner_blocks[inner_index].animate.set_fill(color=get_color(avg_temp)),
]
# Animate all color changes concurrently
if color_animations:
self.play(*color_animations, run_time=color_change_time)
# Pause movement
self.wait(pause_time)
# Final wait
self.wait(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment