Reshape Geometry¶
Sometimes we encounter this situation: we want to reset a shape’s size or contour based on geometric parameters, and we might do this:
# First creation
circle = Circle(radius=2)
...
# ? Reset geometric parameters
circle.become(Circle(radius=1.2))
Although this method works, recreating items this way has two major problems:
We need to temporarily create a
Circle, “borrow” its data, and then discard it immediately, which is cumbersome; and when called frequently, it can slightly hurt performanceThe temporarily created
Circlecannot follow the current item’s position, so extra cumbersome operations are needed for alignment
When you want “the same item, just with a different size or contour”, geometry items provide reshape() to help you do this.
When reshape Fits¶
reshape() is suitable for “parameterized shape changes”, for example:
Change a circle’s radius
Change a rectangle’s width and height
Change a rounded rectangle’s corner radius
Compared with temporarily constructing a new item, reshape() has these advantages:
The code is simpler: just pass new parameters directly, without creating a temporary item
Parameters can be omitted, for example changing only a rounded rectangle’s corner radius while keeping width and height unchanged; note that omitted parameters are determined by values originally passed to the constructor, not by the item’s current width and height
For some geometry items, the current position can be kept unchanged, with no extra alignment operations
Usage¶
You can understand it as “re-describing the current item with new shape parameters”; you can reset some parameters originally passed to the constructor:
item.reshape(...)
In animations, a common form is:
self.play(item.anim.reshape(...))
Below we demonstrate reshape() with two common shapes.
circle = Circle(radius=0.8, color=BLUE, fill_alpha=0.4).show()
self.forward()
self.play(circle.anim.reshape(1.8))
self.forward(0.5)
self.play(circle.anim.reshape(0.5))
self.forward()
circle.hide()
rect = RoundedRect(3.6, 1.6, corner_radius=0.25, color=TEAL, fill_alpha=0.35).show()
self.forward()
self.play(rect.anim.reshape(5.2, 2.4, corner_radius=0.5))
self.forward(0.5)
self.play(rect.anim.reshape(corner_radius=0.15))
self.forward(0.5)
self.play(rect.anim.reshape(UL, DR))
self.forward()
A more complex example:
path = VItem(
[-6.2, 0.76, 0], [-4.45, 0.65, 0], [-3.43, 0.14, 0], [-2.95, -0.11, 0], [-1.89, -0.82, 0],
[-0.64, -1.66, 0], [0.03, -2, 0], [1.3, -2.64, 0], [4.07, -3.28, 0],
color=[BLUE, RED]
).show()
star = Star(start_angle=10 * DEGREES, color=YELLOW, fill_alpha=0.5).show()
star.points.to_border(UR, buff=0.75)
dot = Dot()
arrow = Arrow(color=YELLOW, alpha=[0, 1])
self.play(
MoveAlongPath(dot, path),
DataUpdater(
dot,
lambda data, p:
data.reshape(radius=DEFAULT_DOT_RADIUS * (1 + 3 * p.alpha))
.glow.set(alpha=p.alpha)
),
GroupUpdater(
arrow,
lambda group, p: group.reshape(dot.current(), star)
),
duration=4
)
See also:
Note
The path is drawn using the GUI Draw feature