__all__ = [
'Ruler',
]
# from manim import *
from manim.mobject.geometry.polygram import Rectangle
from manim.mobject.geometry.line import Line
from manim.mobject.types.vectorized_mobject import VGroup
from manim.utils.color import *
from manim.constants import *
import numpy as np
from ..utils.geometry_method import get_vecs_angle
[docs]
class Ruler(VGroup):
'''Ruler mobject.
.. manim:: RulerExample
:save_last_frame:
from manim_extensions.compass import Ruler
class RulerExample(Scene):
def construct(self):
ruler = Ruler()
self.add(ruler)
'''
[docs]
def __init__(
self,
length = 12,
width = 0.8,
ruler_color = WHITE,
stroke_width = 2,
fill_opacity = 0.4,
**kwargs
):
super().__init__(**kwargs)
self.ruler_length = length
self.ruler_width = width
self.ruler_color = ruler_color
self.ruler = Rectangle(
height = self.ruler_width,
width = self.ruler_length,
color = self.ruler_color,
stroke_width = stroke_width,
fill_opacity = fill_opacity,
)
self.add(self.ruler)
[docs]
def get_vecs_of_ruler(self):
'''Return the extension and width directions of the ruler.
.. manim:: GetVecsOfRulerDocExample
:save_last_frame:
from manim import *
from manim_extensions.compass import Ruler
class GetVecsOfRulerDocExample(Scene):
def construct(self):
ruler = Ruler().to_edge(LEFT)
u, v = ruler.get_vecs_of_ruler()
center = ruler.get_middle_point()
self.add(ruler, Arrow(center, center + u), Arrow(center, center + v))
'''
A,B,C,_ = self.ruler.get_vertices()
return Line(B,A).get_unit_vector(),Line(B,C).get_unit_vector()
[docs]
def get_direction_vector_of_ruler(self):
'''Return the extension direction of the ruler.
.. manim:: GetDirectionVectorOfRulerDocExample
:save_last_frame:
from manim import *
from manim_extensions.compass import Ruler
class GetDirectionVectorOfRulerDocExample(Scene):
def construct(self):
ruler = Ruler().to_edge(LEFT)
v = ruler.get_direction_vector_of_ruler()
center = ruler.get_middle_point()
self.add(ruler, Arrow(center, center + v))
'''
s,e,*_ = self.ruler.get_vertices()
return Line(e,s).get_unit_vector()
[docs]
def get_width_vector_of_ruler(self):
'''Return the width direction of the ruler.
.. manim:: GetWidthVectorOfRulerDocExample
:save_last_frame:
from manim import *
from manim_extensions.compass import Ruler
class GetWidthVectorOfRulerDocExample(Scene):
def construct(self):
ruler = Ruler().to_edge(LEFT)
v = ruler.get_width_vector_of_ruler()
center = ruler.get_middle_point()
self.add(ruler, Arrow(center, center + v))
'''
_,s,e,_ = self.ruler.get_vertices()
return Line(e,s).get_unit_vector()
[docs]
def get_start_and_end(self):
'''Return the start and end points of the ruler.
.. manim:: GetStartAndEndDocExample
:save_last_frame:
from manim import *
from manim_extensions.compass import Ruler
class GetStartAndEndDocExample(Scene):
def construct(self):
ruler = Ruler().to_edge(LEFT)
start, end = ruler.get_start_and_end()
self.add(ruler, Dot(start), Dot(end))
'''
E,S,*_ = self.ruler.get_vertices()
return S,E
[docs]
def get_middle_point(self):
'''Return the midpoint of the ruler.
.. manim:: GetMiddlePointDocExample
:save_last_frame:
from manim import *
from manim_extensions.compass import Ruler
class GetMiddlePointDocExample(Scene):
def construct(self):
ruler = Ruler().to_edge(LEFT)
self.add(ruler, Dot(ruler.get_middle_point()))
'''
S,E = self.get_start_and_end()
return (S+E)/2
[docs]
def get_length_of_ruler(self):
'''Return the length of the ruler.
.. manim:: GetLengthOfRulerDocExample
:save_last_frame:
from manim import *
from manim_extensions.compass import Ruler
class GetLengthOfRulerDocExample(Scene):
def construct(self):
ruler = Ruler().to_edge(LEFT)
label = Text(f"length={ruler.get_length_of_ruler():.2f}").to_edge(UP)
self.add(ruler, label)
'''
S,E = self.get_start_and_end()
return np.linalg.norm(E-S)
[docs]
def set_ruler(self,start = LEFT,end = RIGHT):
'''
Place the ruler so that one of its edges aligns with start and end.
Parameters
----------
start
start point of the ruler placement
end
end point of the ruler placement
.. manim:: SetRulerDocExample
:save_last_frame:
from manim import *
from manim_extensions.compass import Ruler
class SetRulerDocExample(Scene):
def construct(self):
ruler = Ruler().set_ruler(LEFT, RIGHT)
self.add(ruler)
'''
direction = end - start
current_pos = self.get_middle_point()
target_pos = (start + end)/2
self.rotate(
angle = get_vecs_angle(
self.get_direction_vector_of_ruler(),
direction
),
about_point = current_pos
).shift(target_pos - current_pos)
return self
[docs]
def put_ruler_flat(self):
'''Lay the ruler flat.
.. manim:: PutRulerFlatDocExample
:save_last_frame:
from manim import *
from manim_extensions.compass import Ruler
class PutRulerFlatDocExample(Scene):
def construct(self):
ruler = Ruler().put_ruler_flat()
self.add(ruler)
'''
self.rotate(
angle = get_vecs_angle(
self.get_direction_vector_of_ruler(),
RIGHT
)
)
return self