3b1b / manim

Animation engine for explanatory math videos
MIT License
68.01k stars 6.07k forks source link

Plot a circle in Manim graph using coordinate equations. #1227

Closed baljeetrathi closed 4 years ago

baljeetrathi commented 4 years ago

Hi,

I want to plot the circle x^2 + y^2 = 25 in Manim. I am currently using the following code to get the corresponding values of y for a given x:

circle = axes.get_graph(
            lambda x: math.sqrt(25 - x**2),
            x_range=[-5,5, 0.01]
        )

However, there will be two values of y for each value of x. This means that I the function only plots a semi-circle. How can I get it to plot the full circle?

Thanks.

NeoPlato commented 4 years ago

Hold on to your hat brother, cause you are about to see a mad lad in action.

circle = axes.get_parametric_curve(
    lambda t: 5 * np.cos(t) * RIGHT + 5 * np.sin(t) * UP,
    t_min = 0,
    t_max = TAU,
    stroke_color = ORANGE,
    stroke_width = 2
)

You get it. It's _get_parametriccurve. You could also create a literal circle mainly because it'll be easier to do animations with, especially transforms into other things like ellipses and stuff. But anyway...

Also don't mind the extra kwargs. I just like my objects looking pretty

baljeetrathi commented 4 years ago

Thanks @NeoPlato 😄

When you say, literal circle, do you mean a circle using the Circle() method in Manim?

NeoPlato commented 4 years ago

Exactly!

Then the radius of $\sqrt{25}$ in the implicit equation is merely the radius of the circle all in a single setting.

Also, you don't have to think about it as much as you would when using the parametric version. Small disadvantage I see here is the circle won't be an attribute of the axes so you'd either move it independently or add a new method to Axes in _manimlib\mobject\coordinatesystems.py to handle this for you, which is recommended.

I think I can sort you out here. Just copy paste this code(better in the CoordinateSystems class than the Axes class since it is the base class thus extending it automatically to ThreeDAxes and NumberPlane and ComplexPlane):

Screenshot 2020-09-13 123337

Add the import line at the top for obvious reasons:

Screenshot 2020-09-13 123548

And you're good to go!

baljeetrathi commented 4 years ago

Thanks @NeoPlato :)

You are awesome. How did you learn so much about Manim? I have been trying to learn some things myself but most old tutorials no longer work.

NeoPlato commented 4 years ago

Oh that's easy.

After banging my head against a wall (figuratively of course) my brain reset and I gave up completely on any outside help.

Since then I've been studying the original master's code and actually learning Python and I can say I'm making good progress.

I still would and do watch videos from Theorem of Beethoven cause you grab knowledge where you see it but at this point I'm a big boy with a big man motto

If you can't do something, find the solution yourself. And if you don't find the solution even if it's there, don't bother, everything in Python is an object, you just craft it yourself

NeoPlato commented 4 years ago

Exactly!

Then the radius of $\sqrt{25}$ in the implicit equation is merely the radius of the circle all in a single setting.

Also, you don't have to think about it as much as you would when using the parametric version. Small disadvantage I see here is the circle won't be an attribute of the axes so you'd either move it independently or add a new method to Axes in _manimlib\mobject\coordinatesystems.py to handle this for you, which is recommended.

I think I can sort you out here. Just copy paste this code(better in the CoordinateSystems class than the Axes class since it is the base class thus extending it automatically to ThreeDAxes and NumberPlane and ComplexPlane):

Screenshot 2020-09-13 123337

Add the import line at the top for obvious reasons:

Screenshot 2020-09-13 123548

And you're good to go!

Quick update on this thing. I just realized that the circle initialized stays at the center meaning if the Axes method was called on a spot that wasn't the origin the circle would be left there undisturbed which is not helpful. Like so:

        axes = Axes(y_min=0)
        axes.shift(DOWN * 3)
        graph = axes.get_circle(radius=3)
        self.add(axes, graph)
        self.play(
            axes.shift, UP * 4,
            run_time = 3
        )
        self.wait()

Try this on the original version and the circle doesn't go to the correct origin.

Solution:

Screenshot 2020-09-13 174313

The play method executed in the code above will leave the circle hanging even though it's been correctly placed this time. For that, remember that Axes is a VGroup so a simple axes.add(circle) will do the trick quite nicely.

Just thought that might help. Happy animating

baljeetrathi commented 4 years ago

Thanks @NeoPlato :)