Code Monkey home page Code Monkey logo

manim-physics's Introduction

manim-physics

Introduction

This is a 2D physics simulation plugin that allows you to generate complicated scenes in various branches of Physics such as rigid mechanics, electromagnetism, wave etc. Due to some reason, I (Matheart) may not have time to maintain this repo, if you want to contribute please seek help from other contributors.

Official Documentation: https://manim-physics.readthedocs.io/en/latest/

Contributors:

Installation

manim-physics is a package on pypi, and can be directly installed using pip:

pip install manim-physics

manim-physics's People

Contributors

icedcoffeeee avatar matheart avatar myzel394 avatar thaza-kun avatar turkeybilly avatar viicos avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

manim-physics's Issues

Make `SpaceScene.make_rigid_body` not take children of `VGroups`

From discord user Naw Sai: SVGMobjects don't work as rigid bodies.

This is because the function SpaceScene.make_rigid_body takes the whole family of the mobject and applies the rigid property; which explains the explosion, as overlap of rigid bodies are considered high powered collisions.

Suggested Changes

I think a good approach would be to make the function disregard families; if the children are intended to be rigid, then an unpacking operator should be used.

Before:

a = VGroup(Circle(), Square().shift(UP*2))
self.make_rigid_body(a)

After:

a = VGroup(Circle(), Square().shift(UP*2))
self.make_rigid_body(*a)

Homogeneous magnetic field?

So I'm currently trying to implement a homogeneous magnetic field. However, I can't get it to work. And basically my question is: Is it even possible to create a homogeneous magnetic field using this library?

The closest thing I could get is this (even tough I needed to remove this if-statement in electromagnetism.py, btw, why did you add it?):

from manim import *
from manim_physics import *


class HorseShoeMagnet(VGroup):
    def __init__(
        self,
        width: float = 6,
        height: float = 6,
        bar_width: Optional[float] = None,
        bar_height: Optional[float] = None,
        field_x_padding: Optional[float] = None,
        field_y_padding: Optional[float] = None,
        field_density: float = 2,
        magnets: list[BarMagnet] = None,
        create_bar: bool = True,
        **kwargs
    ):
        magnets = magnets or []
        field_x_padding = field_x_padding or .3
        field_y_padding = field_y_padding or .3
        bar_width = bar_width or 1
        bar_height = bar_height or 1

        field_width = width - bar_width
        field_height = height - (bar_height * 2)

        bar_magnets = [*magnets]
        surrounding_rectangle = Rectangle(width=0, height=height)

        # Ensures that there is a field
        self.bar_magnet = BarMagnet(width=width, height=height * 5)

        if create_bar:
            bar_magnets.insert(0, self.bar_magnet)

        self.field = BarMagneticField(
            *bar_magnets,
            x_range=[
                -(field_width / 2),
                (field_width / 2 - field_x_padding),
                1 / field_density
            ],
            y_range=[
                -(field_height / 2 - field_y_padding),
                (field_height / 2 - field_y_padding),
                1 / field_density
            ]
        )

        self.north_rectangle = Rectangle(
            width=field_width,
            height=bar_height,
            fill_opacity=1,
            color=RED,
            stroke_width=0,
        )\
            .align_to(surrounding_rectangle, DOWN)
        self.north_side_wall = Rectangle(
            width=bar_width,
            height=height / 2,
            fill_opacity=1,
            color=RED,
            stroke_width=0,
        )\
            .align_to(self.north_rectangle, RIGHT + DOWN)\
            .shift(RIGHT)
        self.north_label = Tex("N").next_to(self.north_rectangle, ORIGIN)
        self.north_parts = VGroup(
            self.north_rectangle,
            self.north_side_wall,
        )

        self.south_rectangle = Rectangle(
            width=field_width,
            height=bar_height,
            fill_opacity=1,
            color=BLUE,
            stroke_width=0,
        )\
            .align_to(surrounding_rectangle, UP)
        self.south_side_wall = Rectangle(
            width=bar_width,
            height=height / 2,
            fill_opacity=1,
            color=BLUE,
            stroke_width=0,
        )\
            .align_to(self.south_rectangle, RIGHT + UP)\
            .shift(RIGHT)
        self.south_label = Tex("S").next_to(self.south_rectangle, ORIGIN)
        self.south_parts = VGroup(
            self.south_rectangle,
            self.south_side_wall,
        )

        super().__init__(**kwargs)
        self.add(
            self.field,
            VGroup(
                self.north_parts,
                self.south_parts,
            ),
            self.north_label,
            self.south_label
        )
        self.add(*magnets, self.bar_magnet.set_opacity(.2))


class FirstFormulaExplainedScene(Scene):
    def construct(self):
        magnet = HorseShoeMagnet(field_density=8, magnets=[BarMagnet().scale(.1)])

        self.add(magnet)

`Charge.point` not updated when moving it

So whenever a Charge object is instanciated, the attribute point is set:

class Charge(VGroup):
def __init__(
self,
magnitude: float = 1,
point: np.ndarray = ORIGIN,
add_glow: bool = True,
**kwargs,
) -> None:
"""An electrostatic charge object. Commonly used for :class:`~ElectricField`.
Parameters
----------
magnitude
The strength of the electrostatic charge.
point
The position of the charge.
add_glow
Whether to add a glowing effect. Adds rings of
varying opacities to simulate glowing effect.
kwargs
Additional parameters to be passed to ``VGroup``.
"""
VGroup.__init__(self, **kwargs)
self.magnitude = magnitude
self.point = point

but this attribute is not updated when using methods such as move_to or shift:

class Sample(Scene):
    def construct(self):
        charge = Charge()
        print(charge.point)
        charge.shift(UP)
        print(charge.point)
>>[0. 0. 0.]
>>[0. 0. 0.]

This implies some incorrect behaviour e.g. when using ElectricField.get_force_on_charge:

class Sample(Scene):
    def construct(self):
        charge_1 = Charge(add_glow=False)
        charge_2 = Charge(add_glow=False).shift(UP)
        field = ElectricField(charge_1)
        f = field.get_force_on_charge(charge_2)
        self.add(charge_1, charge_2, field, f)
Result

Sample_ManimCE_v0 15 2

You can see here that the f vector is still located on the origin, where the charge_2 was previously located.

This happens because the code of the get_force_on_charge method is using the charge.point attribute L147:

def get_force_on_charge(self, charge: Charge, **kwargs) -> Vector:
"""Returns a vector corresponding to the force
of the electric field on the charge.
"""
p = charge.get_center()
direction = np.zeros(3)
for other_charge in self.charges:
if other_charge == charge:
continue
p0, mag = other_charge.get_center(), other_charge.magnitude
x, y, z = p - p0
dist = np.linalg.norm(p - p0) ** 3
if (x**2) > 0.01 or (y**2) > 0.01:
direction += mag * np.array([x / dist, y / dist, 0])
else:
direction += np.zeros(3)
length = (direction[0] ** 2 + direction[1] ** 2) ** 0.5
vec_start = (
Vector(direction / length * charge.radius).shift(charge.point).get_end()
)
return Vector(direction, **kwargs).shift(vec_start)

So maybe to fix this the methods moving the object such as shift, move_to, to_corner should be overrided? The thing is we can't be 100% sure that all the methods modifying the object's position have been taken into account. Maybe there's a more general way of fixing this.

Bump manim version requirement

Manim is currently at version 0.18.0.post0, and remains compatible with manim-physics.

However manim-physics' pyproject specifies:

manim = "^0.17.3"

which causes that any attempt to install manim-physics downgrades installed manim to 0.17.13, and any attempt of upgrading manim after that issues a warning about incompatible requirements with manim-physics.

I think the line in pyproject can be safely changed to:

manim = "^0.17.3,<0.19.0"

Wire is not defined

Hello everyone, this is my first time using manim, manim-physics and GitHub, i hope that i'm doing every fine and respecting all the rules,

So my issue is that i want to create an animation of a magnetic field streamline being blocked by a metallic shield, and as a starter i wanted to try the code provided in the doc, but when i try to input the Wire example in my visual studio i get this message error :

"Wire" is not defined Pylance (reportUndefinedVariable) [Ln 7, Col 16],

How can i solve this ?

Best regards,

make_rigid_body having a bug when applying to string

具体问题发送到群里面了并且私信了
make_rigid_body(string) 只会让最后一个字符掉下去
解决办法:
rigid_mechanics.py 第 56 行和 57 行应该被 indent
要不然只会让字符串的最后一个字符得到效果 而不是每一个字符

Turn off gravity for rigid body

I want to turn off gravity for one scene, but methods from pymunk docs does not works.
Firstly I tryied to change scene space gravity paramether in construct method:

def construct(self):
        self.space.gravity = 0, 0```

But it doesn't help
Then i tried to override init method for Space scene class, but it did not bring any result

    def __init__(self, renderer=None, **kwargs):
        self.space = Space(gravity=(0, 0))
        super().__init__(renderer=renderer, **kwargs)

Full code:

from manim import *
from manim_physics import *

class FirstScene(SpaceScene):   
    def __init__(self, renderer=None, **kwargs):
        self.space = Space(gravity=(0, 0))
        super().__init__(renderer=renderer, **kwargs)

    def construct(self):
        self.space.gravity = 0, 0
        c1 = Circle(color="red").shift(2* LEFT)
        c2 = Circle(color="blue").shift(RIGHT)
        self.make_rigid_body(c1, c2)
        c1.body.velocity = (1, 0)
        self.wait(10)

Methods don't work

You can't execute any methods once the animations for each object are started. Example:

class WaveScene(Scene):
    def construct(self):
        wave = StandingWave(2, color=YELLOW)

        self.add(wave)

        wave.start_wave()  # Troublemaker

        self.wait(1)
        self.play(
            ApplyMethod(wave.shift, DOWN)
        )
        self.wait(10)

The wave doesn't move down when using wave.start_wave() before.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.