You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
After a rotation or reflection which moves a Circle's starting point away from the RIGHT axis, Circle.point_at_angle() returns incorrect results.
Expected behavior
When calling Circle.point_at_angle(), an angle of 0 should return the point at Circle.points[0], no matter how the Circle has been rotated or reflected.
When calling Circle.point_at_angle() with a nonzero angle, the sign of the angle value should correspond to the Circle's reflections (i.e. for an un-reflected Circle, a positive angle should proceed counter-clockwise; a positive angle on a reflected circle should proceed clockwise.
How to reproduce the issue
Code for reproducing the problem
frommanimimport*frommanim.typingimport*classtestCirclePointAtAngle(Scene):
defconstruct(self):
# Flip circle so that it starts on LEFT, then rotate 1/4 turn clockwise# At the end of this, the start of the circle is at UP, and it proceeds clockwise from therebad_circle= (
Circle(radius=2, stroke_color=RED)
.flip()
.rotate(1/4*-TAU)
.move_to(LEFT*3)
)
bad_text=Text(
"using Circle.point_at_angle()", color=RED, font_size=24
).next_to(bad_circle, DOWN)
good_circle= (
Circle(radius=2, stroke_color=GREEN)
.flip()
.rotate(1/4*-TAU)
.move_to(RIGHT*3)
)
good_text=Text("fixed version", color=GREEN, font_size=24).next_to(
good_circle, DOWN
)
self.play(
Create(bad_circle), Create(bad_text), Create(good_circle), Create(good_text)
)
self.wait(1)
deffixed_point_at_angle(circle: Circle, angle: float) ->Point3D:
proportion= (angle) /TAUproportion-=np.floor(proportion)
returncircle.point_from_proportion(proportion)
# Create 12 white dots, spaced evenly around the circle, STARTING where the circle starts.foriinrange(12):
# BUG: These dots start at LEFT instead of UP.# This is because of the logic in point_at_angle:# - start_angle is computed by projecting circle.points[0] onto the XY plane,# then reading its angle via angle_of_vector() .. as if the circle was still in "mathematical" orientation.# here, `start_angle` takes the value 1.570796..., i.e. 90° counterclockwise from mathemetical 0° rotation.# - proportion is then computed as (angle - start_angle) / TAU.# but param `angle` is "The angle of the point along the circle in radians." Doesn't that mean "from self.points[0]"?# shouldn't `angle=0` return a point at `self.points[0]`?# instead proportion takes (0 - 1.570796...) / TAU = -0.75, then the cycling with `np.floor()` brings it to 0.25.# TODO: fix for this should be to just remove start_angle in point_at_angle(). calculate `proportion` as `angle / TAU`.self.add(
Point(
bad_circle.point_at_angle(TAU*i/12),
color=WHITE,
stroke_width=10,
)
)
self.add(
Point(
fixed_point_at_angle(good_circle, TAU*i/12),
color=WHITE,
stroke_width=10,
)
)
self.wait(0.3333333)
self.wait(1)
Additional media files
Images/GIFstestCirclePointAtAngle.mp4
Logs
Terminal output
❯ "/mnt/c/Users/pikab/Programming/Personal/harmonimation/.venv/bin/manim" "/mnt/c/Users/pikab/Programming/Personal/harmonimation/renderer/play.py" testCirclePointAtAngle --disable_caching -v DEBUG
Manim Community v0.19.0
[05/04/25 04:19:27] INFO Caching disabled. cairo_renderer.py:79
DEBUG List of the first few animation hashes of the scene: ['uncached_00000'] cairo_renderer.py:98
[05/04/25 04:19:30] INFO Animation 0 : Partial movie file written in '/mnt/c/Users/pikab/Programming/Personal/harmonimation/media/videos/play/1080p60/partial_movie_files/testCirclePointAtAngle/uncached_00000.mp4' scene_file_writer.py:588
DEBUG Animation with empty mobject animation.py:190
INFO Caching disabled. cairo_renderer.py:79
DEBUG List of the first few animation hashes of the scene: ['uncached_00000', 'uncached_00001'] cairo_renderer.py:98
[05/04/25 04:19:32] INFO Animation 1 : Partial movie file written in '/mnt/c/Users/pikab/Programming/Personal/harmonimation/media/videos/play/1080p60/partial_movie_files/testCirclePointAtAngle/uncached_00001.mp4' scene_file_writer.py:588
DEBUG Animation with empty mobject animation.py:190
INFO Caching disabled. cairo_renderer.py:79
DEBUG List of the first few animation hashes of the scene: ['uncached_00000', 'uncached_00001', 'uncached_00002'] cairo_renderer.py:98
[05/04/25 04:19:33] INFO Animation 2 : Partial movie file written in '/mnt/c/Users/pikab/Programming/Personal/harmonimation/media/videos/play/1080p60/partial_movie_files/testCirclePointAtAngle/uncached_00002.mp4' scene_file_writer.py:588
DEBUG Animation with empty mobject animation.py:190
INFO Caching disabled. cairo_renderer.py:79
DEBUG List of the first few animation hashes of the scene: ['uncached_00000', 'uncached_00001', 'uncached_00002', 'uncached_00003'] cairo_renderer.py:98
INFO Animation 3 : Partial movie file written in '/mnt/c/Users/pikab/Programming/Personal/harmonimation/media/videos/play/1080p60/partial_movie_files/testCirclePointAtAngle/uncached_00003.mp4' scene_file_writer.py:588
DEBUG Animation with empty mobject animation.py:190
INFO Caching disabled. cairo_renderer.py:79
DEBUG List of the first few animation hashes of the scene: ['uncached_00000', 'uncached_00001', 'uncached_00002', 'uncached_00003', 'uncached_00004'] cairo_renderer.py:98
[05/04/25 04:19:34] INFO Animation 4 : Partial movie file written in '/mnt/c/Users/pikab/Programming/Personal/harmonimation/media/videos/play/1080p60/partial_movie_files/testCirclePointAtAngle/uncached_00004.mp4' scene_file_writer.py:588
DEBUG Animation with empty mobject animation.py:190
INFO Caching disabled. cairo_renderer.py:79
DEBUG List of the first few animation hashes of the scene: ['uncached_00000', 'uncached_00001', 'uncached_00002', 'uncached_00003', 'uncached_00004'] cairo_renderer.py:98
INFO Animation 5 : Partial movie file written in '/mnt/c/Users/pikab/Programming/Personal/harmonimation/media/videos/play/1080p60/partial_movie_files/testCirclePointAtAngle/uncached_00005.mp4' scene_file_writer.py:588
DEBUG Animation with empty mobject animation.py:190
INFO Caching disabled. cairo_renderer.py:79
DEBUG List of the first few animation hashes of the scene: ['uncached_00000', 'uncached_00001', 'uncached_00002', 'uncached_00003', 'uncached_00004'] cairo_renderer.py:98
[05/04/25 04:19:35] INFO Animation 6 : Partial movie file written in '/mnt/c/Users/pikab/Programming/Personal/harmonimation/media/videos/play/1080p60/partial_movie_files/testCirclePointAtAngle/uncached_00006.mp4' scene_file_writer.py:588
DEBUG Animation with empty mobject animation.py:190
INFO Caching disabled. cairo_renderer.py:79
DEBUG List of the first few animation hashes of the scene: ['uncached_00000', 'uncached_00001', 'uncached_00002', 'uncached_00003', 'uncached_00004'] cairo_renderer.py:98
INFO Animation 7 : Partial movie file written in '/mnt/c/Users/pikab/Programming/Personal/harmonimation/media/videos/play/1080p60/partial_movie_files/testCirclePointAtAngle/uncached_00007.mp4' scene_file_writer.py:588
DEBUG Animation with empty mobject animation.py:190
INFO Caching disabled. cairo_renderer.py:79
DEBUG List of the first few animation hashes of the scene: ['uncached_00000', 'uncached_00001', 'uncached_00002', 'uncached_00003', 'uncached_00004'] cairo_renderer.py:98
[05/04/25 04:19:36] INFO Animation 8 : Partial movie file written in '/mnt/c/Users/pikab/Programming/Personal/harmonimation/media/videos/play/1080p60/partial_movie_files/testCirclePointAtAngle/uncached_00008.mp4' scene_file_writer.py:588
DEBUG Animation with empty mobject animation.py:190
INFO Caching disabled. cairo_renderer.py:79
DEBUG List of the first few animation hashes of the scene: ['uncached_00000', 'uncached_00001', 'uncached_00002', 'uncached_00003', 'uncached_00004'] cairo_renderer.py:98
INFO Animation 9 : Partial movie file written in '/mnt/c/Users/pikab/Programming/Personal/harmonimation/media/videos/play/1080p60/partial_movie_files/testCirclePointAtAngle/uncached_00009.mp4' scene_file_writer.py:588
DEBUG Animation with empty mobject animation.py:190
INFO Caching disabled. cairo_renderer.py:79
DEBUG List of the first few animation hashes of the scene: ['uncached_00000', 'uncached_00001', 'uncached_00002', 'uncached_00003', 'uncached_00004'] cairo_renderer.py:98
[05/04/25 04:19:37] INFO Animation 10 : Partial movie file written in '/mnt/c/Users/pikab/Programming/Personal/harmonimation/media/videos/play/1080p60/partial_movie_files/testCirclePointAtAngle/uncached_00010.mp4' scene_file_writer.py:588
DEBUG Animation with empty mobject animation.py:190
INFO Caching disabled. cairo_renderer.py:79
DEBUG List of the first few animation hashes of the scene: ['uncached_00000', 'uncached_00001', 'uncached_00002', 'uncached_00003', 'uncached_00004'] cairo_renderer.py:98
INFO Animation 11 : Partial movie file written in '/mnt/c/Users/pikab/Programming/Personal/harmonimation/media/videos/play/1080p60/partial_movie_files/testCirclePointAtAngle/uncached_00011.mp4' scene_file_writer.py:588
DEBUG Animation with empty mobject animation.py:190
INFO Caching disabled. cairo_renderer.py:79
DEBUG List of the first few animation hashes of the scene: ['uncached_00000', 'uncached_00001', 'uncached_00002', 'uncached_00003', 'uncached_00004'] cairo_renderer.py:98
[05/04/25 04:19:38] INFO Animation 12 : Partial movie file written in '/mnt/c/Users/pikab/Programming/Personal/harmonimation/media/videos/play/1080p60/partial_movie_files/testCirclePointAtAngle/uncached_00012.mp4' scene_file_writer.py:588
DEBUG Animation with empty mobject animation.py:190
INFO Caching disabled. cairo_renderer.py:79
DEBUG List of the first few animation hashes of the scene: ['uncached_00000', 'uncached_00001', 'uncached_00002', 'uncached_00003', 'uncached_00004'] cairo_renderer.py:98
INFO Animation 13 : Partial movie file written in '/mnt/c/Users/pikab/Programming/Personal/harmonimation/media/videos/play/1080p60/partial_movie_files/testCirclePointAtAngle/uncached_00013.mp4' scene_file_writer.py:588
DEBUG Animation with empty mobject animation.py:190
INFO Caching disabled. cairo_renderer.py:79
DEBUG List of the first few animation hashes of the scene: ['uncached_00000', 'uncached_00001', 'uncached_00002', 'uncached_00003', 'uncached_00004'] cairo_renderer.py:98
[05/04/25 04:19:39] INFO Animation 14 : Partial movie file written in '/mnt/c/Users/pikab/Programming/Personal/harmonimation/media/videos/play/1080p60/partial_movie_files/testCirclePointAtAngle/uncached_00014.mp4' scene_file_writer.py:588
INFO Combining to Movie file. scene_file_writer.py:739
DEBUG Partial movie files to combine (15 files): ['/mnt/c/Users/pikab/Programming/Personal/harmonimation/media/videos/play/1080p60/partial_movie_files/testCirclePointAtAngle/uncached_00000.mp4', scene_file_writer.py:622
'/mnt/c/Users/pikab/Programming/Personal/harmonimation/media/videos/play/1080p60/partial_movie_files/testCirclePointAtAngle/uncached_00001.mp4',
'/mnt/c/Users/pikab/Programming/Personal/harmonimation/media/videos/play/1080p60/partial_movie_files/testCirclePointAtAngle/uncached_00002.mp4',
'/mnt/c/Users/pikab/Programming/Personal/harmonimation/media/videos/play/1080p60/partial_movie_files/testCirclePointAtAngle/uncached_00003.mp4',
'/mnt/c/Users/pikab/Programming/Personal/harmonimation/media/videos/play/1080p60/partial_movie_files/testCirclePointAtAngle/uncached_00004.mp4']
[05/04/25 04:19:40] INFO scene_file_writer.py:886
File ready at '/mnt/c/Users/pikab/Programming/Personal/harmonimation/media/videos/play/1080p60/testCirclePointAtAngle.mp4'
INFO Rendered testCirclePointAtAngle scene.py:255
Played 15 animations
System specifications
System Details
OS: Windows 11 Version 10.0.22631 Build 22631
RAM: 48.0 GB
Python version (python/py/python3 --version): 3.13.2
Description of bug / unexpected behavior
After a rotation or reflection which moves a Circle's starting point away from the RIGHT axis,
Circle.point_at_angle()
returns incorrect results.Expected behavior
Circle.point_at_angle()
, an angle of0
should return the point atCircle.points[0]
, no matter how the Circle has been rotated or reflected.Circle.point_at_angle()
with a nonzeroangle
, the sign of theangle
value should correspond to the Circle's reflections (i.e. for an un-reflected Circle, a positiveangle
should proceed counter-clockwise; a positiveangle
on a reflected circle should proceed clockwise.How to reproduce the issue
Code for reproducing the problem
Additional media files
Images/GIFs
testCirclePointAtAngle.mp4
Logs
Terminal output
System specifications
System Details
python/py/python3 --version
):3.13.2
pip list
):LaTeX details
Additional comments
This should be the body of the corrected
Circle.point_at_angle()
:The text was updated successfully, but these errors were encountered: