Skip to content

Instantly share code, notes, and snippets.

@uwezi
Last active June 26, 2026 22:33
Show Gist options
  • Select an option

  • Save uwezi/68b51e6acf642351e02c73e69ecaeb3c to your computer and use it in GitHub Desktop.

Select an option

Save uwezi/68b51e6acf642351e02c73e69ecaeb3c to your computer and use it in GitHub Desktop.
[Compass] A compass mobject for Manim. #manim #geometry
class Compass(VGroup):
def __init__(self, arm_length=3, arm_width=.2, angle=15*DEGREES, left_color=RED, right_color=YELLOW,):
super().__init__()
self.left_arm = Polygon(
[0,0,0],[0,arm_length,0],[-arm_width,arm_length,0],[-arm_width,arm_width,0],
stroke_width=0,
fill_color=left_color,
fill_opacity=1
)
self.right_arm = Polygon(
[0,0,0],[0,arm_length,0],[arm_width,arm_length,0],[arm_width,arm_width,0],
stroke_width=0,
fill_color=right_color,
fill_opacity=1
)
self.handle = VGroup(
Circle(radius=2*arm_width),
Rectangle(width=arm_width,height=4*arm_width).shift([0,2*arm_width,0])
).set_stroke(width=0).set_fill(color=WHITE,opacity=1)
self.handle.shift(self.get_pivot())
self.set_angle(angle=angle)
self.add(self.left_arm, self.right_arm, self.handle)
def get_left_point(self):
return self.left_arm.get_vertices()[0]
def get_right_point(self):
return self.right_arm.get_vertices()[0]
def get_pivot(self):
return self.right_arm.get_vertices()[1]
def set_angle(self, angle=15*DEGREES):
curr_langle = Line(self.left_arm.get_vertices()[0],self.left_arm.get_vertices()[1]).get_angle()
curr_rangle = Line(self.right_arm.get_vertices()[0],self.right_arm.get_vertices()[1]).get_angle()
curr_angle = curr_rangle-curr_langle
self.left_arm.rotate(angle=curr_angle/2-angle/2,about_point=self.get_left_point())
self.right_arm.rotate(angle=-curr_angle/2+angle/2,about_point=self.right_arm.get_vertices()[1])
self.right_arm.shift(self.left_arm.get_vertices()[1]-self.right_arm.get_vertices()[1])
self.handle.shift(self.left_arm.get_vertices()[1]-self.handle[0].get_center())
def set_width(self, width=5):
angle = np.asin(0.5*width/np.linalg.norm(self.left_arm.get_vertices()[1]-self.left_arm.get_vertices()[0]))
self.set_angle(angle=2*angle)
class CompassDemo(Scene):
def construct(self):
self.add(NumberPlane())
cmp = Compass(angle=40*DEGREES)
self.add(cmp)
self.wait()
self.play(Rotate(cmp,-40*DEGREES,about_point=ORIGIN))
self.wait()
self.play(cmp.animate.set_angle(30*DEGREES))
self.wait()
self.play(Rotate(cmp,40*DEGREES,about_point=ORIGIN))
self.wait()
self.play(cmp.animate.set_width(3))
self.wait()
tp = TracedPath(
cmp.get_right_point
)
self.add(tp)
self.play(
Rotate(cmp,2*PI,about_point=cmp.get_left_point()),
run_time=3,
rate_func=rate_functions.linear
)
self.wait()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment