Skip to content

Instantly share code, notes, and snippets.

@RadimBaca
Last active February 12, 2024 10:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RadimBaca/98708409a8a653901d79362a9c790b88 to your computer and use it in GitHub Desktop.
Save RadimBaca/98708409a8a653901d79362a9c790b88 to your computer and use it in GitHub Desktop.
Manim pymunk integration. Fluid simulation.
import pymunk
from manim import *
import random
# transform the pymunk position to manim position
def transform_pymunk_to_manim_position(p):
return p[0] / 100.0, p[1] / 100.0, 0
class PymunkCircle(Circle):
def __init__(self, x, y, mass, moment, space, radius, **kwargs):
self.body = pymunk.Body(mass, moment)
self.body.position = x, y
self.shape = pymunk.Circle(self.body, radius)
self.shape.elasticity = 0.93
space.add(self.body, self.shape)
super().__init__(radius=radius / 100.0, **kwargs)
def update_position(self):
position = transform_pymunk_to_manim_position(self.body.position)
self.move_to(position)
class PymunkLine(Line):
def __init__(self, p1, p2, space, elasticity, stroke_width, **kwargs):
self.shape = pymunk.Segment(space.static_body, p1, p2, stroke_width)
self.shape.elasticity = elasticity
space.add(self.shape)
super().__init__(start=transform_pymunk_to_manim_position(p1), end=transform_pymunk_to_manim_position(p2), stroke_width=stroke_width, **kwargs)
class TestPymunk(Scene):
def construct(self):
def update_circle(mo, dt):
mo.update_position()
def update_scene(dt):
self.space.step(1/FPS)
FPS = 80.0
self.space = pymunk.Space()
self.space.gravity = 0, -200
p1 = (-200, -200)
p2 = (200, -200)
p3 = (-200, 200)
p4 = (200, 200)
stroke_width = 3
barier1 = PymunkLine(p1, p2, self.space, 1, stroke_width=stroke_width)
barier2 = PymunkLine(p1, p3, self.space, 1, stroke_width=stroke_width)
barier3 = PymunkLine(p2, p4, self.space, 1, stroke_width=stroke_width)
PymunkCircle.set_default(radius=3, fill_color=BLUE, fill_opacity=0.8, stroke_opacity=1, stroke_width=2, color=BLUE)
circles_count = 1500
circles = VGroup(*[PymunkCircle((i % 30) * 10 - 180 + int(i / 30) * 1,
int(i / 30) * 10 - 150,
mass=5, moment=100, space=self.space) for i in range(circles_count)])
[circles[i].add_updater(update_circle) for i in range(circles_count)]
self.add_updater(update_scene)
self.wait(0.1)
self.add(circles, barier1, barier2, barier3)
self.wait(10)
with tempconfig({"quality": "high_quality", "preview": True}):
TestPymunk().render()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment