Created
September 9, 2024 21:49
-
-
Save thomasahle/c4ce7526f93bff79eea01c1b93193703 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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