Skip to content

Commit 1340c5e

Browse files
abul4fiaJasonGrace2282
authored andcommitted
Fix bug in :class:.VMobjectFromSVGPath (#3677)
* Fixes #3676 * Update manim/mobject/svg/svg_mobject.py Co-authored-by: adeshpande <[email protected]> * Fixed problem and added test --------- Co-authored-by: adeshpande <[email protected]>
1 parent e66c580 commit 1340c5e

File tree

3 files changed

+89
-10
lines changed

3 files changed

+89
-10
lines changed

manim/mobject/svg/svg_mobject.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -510,17 +510,15 @@ def handle_commands(self) -> None:
510510
all_points: list[np.ndarray] = []
511511
last_move = None
512512
curve_start = None
513+
last_true_move = None
513514

514-
# These lambdas behave the same as similar functions in
515-
# vectorized_mobject, except they add to a list of points instead
516-
# of updating this Mobject's numpy array of points. This way,
517-
# we don't observe O(n^2) behavior for complex paths due to
518-
# numpy's need to re-allocate memory on every append.
519-
def move_pen(pt):
520-
nonlocal last_move, curve_start
515+
def move_pen(pt, *, true_move: bool = False):
516+
nonlocal last_move, curve_start, last_true_move
521517
last_move = pt
522518
if curve_start is None:
523519
curve_start = last_move
520+
if true_move:
521+
last_true_move = last_move
524522

525523
if self.n_points_per_curve == 4:
526524

@@ -568,7 +566,7 @@ def add_line(start, end):
568566
for segment in self.path_obj:
569567
segment_class = segment.__class__
570568
if segment_class == se.Move:
571-
move_pen(_convert_point_to_3d(*segment.end))
569+
move_pen(_convert_point_to_3d(*segment.end), true_move=True)
572570
elif segment_class == se.Line:
573571
add_line(last_move, _convert_point_to_3d(*segment.end))
574572
elif segment_class == se.QuadraticBezier:
@@ -588,8 +586,8 @@ def add_line(start, end):
588586
# If the SVG path naturally ends at the beginning of the curve,
589587
# we do *not* need to draw a closing line. To account for floating
590588
# point precision, we use a small value to compare the two points.
591-
if abs(np.linalg.norm(last_move - curve_start)) > 0.0001:
592-
add_line(last_move, curve_start)
589+
if abs(np.linalg.norm(last_move - last_true_move)) > 0.0001:
590+
add_line(last_move, last_true_move)
593591
curve_start = None
594592
else:
595593
raise AssertionError(f"Not implemented: {segment_class}")

tests/module/mobject/svg/test_svg_mobject.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,71 @@ def test_closed_path_does_not_have_extra_point():
134134
),
135135
decimal=5,
136136
)
137+
138+
139+
def test_close_command_closes_last_move_not_the_starting_one():
140+
# This A.svg is the output of a Text("A") in some systems
141+
# It contains a path that moves from the outer boundary of the A
142+
# to the boundary of the inner triangle, anc then closes the path
143+
# which should close the inner triangle and not the outer boundary.
144+
svg = SVGMobject(
145+
get_svg_resource("A.svg"),
146+
)
147+
assert len(svg.points) == 0, svg.points
148+
assert len(svg.submobjects) == 1, svg.submobjects
149+
capital_A = svg.submobjects[0]
150+
151+
# The last point should not be the same as the first point
152+
assert not all(capital_A.points[0] == capital_A.points[-1])
153+
np.testing.assert_almost_equal(
154+
capital_A.points,
155+
np.array(
156+
[
157+
[-0.8380339075214888, -1.0, 1.2246467991473532e-16],
158+
[-0.6132152047642527, -0.3333333333333336, 4.082155997157847e-17],
159+
[-0.388396502007016, 0.3333333333333336, -4.082155997157847e-17],
160+
[-0.16357779924977994, 1.0, -1.2246467991473532e-16],
161+
[-0.16357779924977994, 1.0, -1.2246467991473532e-16],
162+
[-0.05425733591657368, 1.0, -1.2246467991473532e-16],
163+
[0.05506312741663405, 1.0, -1.2246467991473532e-16],
164+
[0.16438359074984032, 1.0, -1.2246467991473532e-16],
165+
[0.16438359074984032, 1.0, -1.2246467991473532e-16],
166+
[0.3889336963403905, 0.3333333333333336, -4.082155997157847e-17],
167+
[0.6134838019309422, -0.3333333333333336, 4.082155997157847e-17],
168+
[0.8380339075214923, -1.0, 1.2246467991473532e-16],
169+
[0.8380339075214923, -1.0, 1.2246467991473532e-16],
170+
[0.744560897060354, -1.0, 1.2246467991473532e-16],
171+
[0.6510878865992157, -1.0, 1.2246467991473532e-16],
172+
[0.5576148761380774, -1.0, 1.2246467991473532e-16],
173+
[0.5576148761380774, -1.0, 1.2246467991473532e-16],
174+
[0.49717968849274957, -0.8138597980824822, 9.966907966764229e-17],
175+
[0.4367445008474217, -0.6277195961649644, 7.687347942054928e-17],
176+
[0.3763093132020939, -0.4415793942474466, 5.407787917345625e-17],
177+
[0.3763093132020939, -0.4415793942474466, 5.407787917345625e-17],
178+
[0.12167600863867864, -0.4415793942474466, 5.407787917345625e-17],
179+
[-0.13295729592473662, -0.4415793942474466, 5.407787917345625e-17],
180+
[-0.38759060048815186, -0.4415793942474466, 5.407787917345625e-17],
181+
[-0.38759060048815186, -0.4415793942474466, 5.407787917345625e-17],
182+
[-0.4480257881334797, -0.6277195961649644, 7.687347942054928e-17],
183+
[-0.5084609757788076, -0.8138597980824822, 9.966907966764229e-17],
184+
[-0.5688961634241354, -1.0, 1.2246467991473532e-16],
185+
[-0.5688961634241354, -1.0, 1.2246467991473532e-16],
186+
[-0.6586087447899202, -1.0, 1.2246467991473532e-16],
187+
[-0.7483213261557048, -1.0, 1.2246467991473532e-16],
188+
[-0.8380339075214888, -1.0, 1.2246467991473532e-16],
189+
[0.3021757525699033, -0.21434317946653003, 2.6249468865275272e-17],
190+
[0.1993017037512583, 0.09991949373745423, -1.2236608817799732e-17],
191+
[0.09642765493261184, 0.4141821669414385, -5.072268650087473e-17],
192+
[-0.006446393886033166, 0.7284448401454228, -8.920876418394973e-17],
193+
[-0.006446393886033166, 0.7284448401454228, -8.920876418394973e-17],
194+
[-0.10905185929034443, 0.4141821669414385, -5.072268650087473e-17],
195+
[-0.2116573246946542, 0.09991949373745423, -1.2236608817799732e-17],
196+
[-0.31426279009896546, -0.21434317946653003, 2.6249468865275272e-17],
197+
[-0.31426279009896546, -0.21434317946653003, 2.6249468865275272e-17],
198+
[-0.10878327587600921, -0.21434317946653003, 2.6249468865275272e-17],
199+
[0.09669623834694704, -0.21434317946653003, 2.6249468865275272e-17],
200+
[0.3021757525699033, -0.21434317946653003, 2.6249468865275272e-17],
201+
]
202+
),
203+
decimal=5,
204+
)
Lines changed: 13 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)