Adding voltage and current labels¶
Voltage label¶
Voltage labels are administered through the Voltage class, which has a very
similar interface to that of Wire. However, as our voltage arrow is going
across a single component, we can use the voltage() method as a
shorthand.
Let’s add one in.
class CurrentShunt(Scene):
def construct(self):
r1 = Resistor().rotate(90 * DEGREES)
r2 = Resistor().rotate(90 * DEGREES).shift(2 * RIGHT)
isource = CurrentSource().rotate(90 * DEGREES).shift(2 * LEFT)
top_node = Node().shift(UP)
bottom_node = Node().shift(DOWN)
r1.set_label("R_1")
r2.set_label("R_2")
isource.set_current("I_0")
c = (Circuit(r1, r2, isource, top_node, bottom_node)
.connect(isource.right, top_node.left)
.connect(r1.right, top_node.down)
.connect(r2.right, top_node.right)
.connect(isource.left, bottom_node.left)
.connect(isource.left, bottom_node.left)
.connect(r1.left, bottom_node.up)
.connect(r2.left, bottom_node.right))
self.add(c)
self.add(r2.voltage("left", "right", "V"))
Note
There are two ways of telling a component-specific voltage arrow which terminals to
attach to. You can either pass in the terminals just as you would for a standard
voltage or wire (so in this case, r2.left and r2.right), or you can pass
strings of the terminal names, which is quicker, and so I opted for it here.
This gives us a beautiful voltage arrow as below.
The voltage arrow is clever — because we constructed it using R2’s method, it knows
to avoid R2 and its labels and annotations. See the Voltage documentation
for more details.
Current labels¶
There are two ways to add current labels to terminals in manim-eng: one is to use the
set_current() method on Terminal, and the other is to use
the set_current() method on Component. Both have their
advantages and drawbacks, but the main points are:
Using the first method allows static code analysers (such as those built-in to all modern IDEs) to verify that the terminal you’re trying to use actually exists on the component.
The second method, whilst indirect, returns the component it was called on, allowing for method chaining.
As we used the second method back when we were adding components to our scene, we’ll use the first method now.
class CurrentShunt(Scene):
def construct(self):
r1 = Resistor().rotate(90 * DEGREES)
r2 = Resistor().rotate(90 * DEGREES).shift(2 * RIGHT)
isource = CurrentSource().rotate(90 * DEGREES).shift(2 * LEFT)
top_node = Node().shift(UP)
bottom_node = Node().shift(DOWN)
r1.set_label("R_1")
r1.right.set_current("I_1")
r2.set_label("R_2")
r2.right.set_current("I_2")
isource.set_current("I_0")
c = (Circuit(r1, r2, isource, top_node, bottom_node)
.connect(isource.right, top_node.left)
.connect(r1.right, top_node.down)
.connect(r2.right, top_node.right)
.connect(isource.left, bottom_node.left)
.connect(isource.left, bottom_node.left)
.connect(r1.left, bottom_node.up)
.connect(r2.left, bottom_node.right))
self.add(c)
self.add(r2.voltage("left", "right", "V"))
This gives us the result below.
Tweaking the voltage label¶
The above looks pretty good, but it’s a little annoying how the voltage arrow collides with the I2 current arrow. We can avoid this by changing the buffer. There are two types of buffer on a voltage arrow:
The
buff, which is the buffer between the end of the voltage arrow and the terminals it is attached to; andThe
component_buff, which is the buffer applied between the arrow and the component it is attached to (if any). Thecomponent_buffimpacts the curvature of the arrow.
We’ll adjust the component_buff for our purposes.
class CurrentShunt(Scene):
def construct(self):
r1 = Resistor().rotate(90 * DEGREES)
r2 = Resistor().rotate(90 * DEGREES).shift(2 * RIGHT)
isource = CurrentSource().rotate(90 * DEGREES).shift(2 * LEFT)
top_node = Node().shift(UP)
bottom_node = Node().shift(DOWN)
r1.set_label("R_1")
r1.right.set_current("I_1")
r2.set_label("R_2")
r2.right.set_current("I_2")
isource.set_current("I_0")
c = (Circuit(r1, r2, isource, top_node, bottom_node)
.connect(isource.right, top_node.left)
.connect(r1.right, top_node.down)
.connect(r2.right, top_node.right)
.connect(isource.left, bottom_node.left)
.connect(isource.left, bottom_node.left)
.connect(r1.left, bottom_node.up)
.connect(r2.left, bottom_node.right))
self.add(c)
self.add(r2.voltage("left", "right", "V", component_buff=0.35))
And with that, we’ve got our full circuit! With that, you should be at least aware of the important aspects of manim-eng that make it tick (at least, aware enough to know where to start digging).
However, there’s one last thing we need to touch on — animations!