Skip to content

Instantly share code, notes, and snippets.

@thomasahle
Created September 9, 2024 21:49
Show Gist options
  • Save thomasahle/c4ce7526f93bff79eea01c1b93193703 to your computer and use it in GitHub Desktop.
Save thomasahle/c4ce7526f93bff79eea01c1b93193703 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
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 = 4 * num_blocks # Number of steps for a full cycle
# 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, start_angle=0):
for i, block in enumerate(blocks):
angle = i * PI / num_blocks + start_angle
block.move_to(radius * np.array([np.cos(angle), np.sin(angle), 0]))
block.rotate(angle)
position_blocks(outer_blocks, outer_radius)
position_blocks(inner_blocks, inner_radius, PI)
# 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
self.play(
outer_blocks.animate.rotate(PI / num_blocks / 2, about_point=ORIGIN),
inner_blocks.animate.rotate(-PI / num_blocks / 2, about_point=ORIGIN),
run_time=step_time,
rate_func=linear,
)
# Pause movement
self.wait(pause_time)
# Perform heat transfer and prepare color change animations
color_animations = []
print("Offset:", offset)
for i in range(num_blocks):
outer_index = (num_blocks - 1 - i) % (2 * num_blocks)
inner_index = (offset - i) % (2 * num_blocks)
print(outer_index, inner_index)
if inner_index < 0 or inner_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.extend(
[
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