Ir al contenido

Figuras geométricas

Manim trae una gran colección de figuras geométricas por defecto. Los podemos agrupar en 4 grandes categorías:

  • Líneas
  • Curvas
  • Polígonos
  • Flechas

Tan simple como suena: Líneas de las cuales definimos un principio y un fin. Podemos agregarles un valor en el parámetro path_arc para que se curven:

lines.py
from manim import *
class LineExample(Scene):
def construct(self):
line1 = Line(LEFT*2, RIGHT*2)
line2 = Line(LEFT*2, RIGHT*2, buff=0.5)
line3 = Line(LEFT*2, RIGHT*2, path_arc=PI/2)
grp = VGroup(line1,line2,line3).arrange(DOWN, buff=2)
self.add(grp)

Todos aquellos objetos que se componen con curvas, desde un arco hasta un círculo:

arc_example.py
from manim import *
class ArcExample(Scene):
def construct(self):
self.add(Arc(angle=PI))
circle_example.py
from manim import *
class CircleExample(Scene):
def construct(self):
circle_1 = Circle(radius=1.0)
circle_2 = Circle(radius=1.5, color=GREEN)
circle_3 = Circle(radius=1.0, color=BLUE_B, fill_opacity=1)
circle_group = Group(circle_1, circle_2, circle_3).arrange(buff=1)
self.add(circle_group)
arc_between_points_example.py
from manim import *
class ArcBetweenPointsExample(Scene):
def construct(self):
circle = Circle(radius=2, stroke_color=GREY)
dot_1 = Dot(color=GREEN).move_to([2, 0, 0]).scale(0.5)
dot_1_text = Tex("(2,0)").scale(0.5).next_to(dot_1, RIGHT).set_color(BLUE)
dot_2 = Dot(color=GREEN).move_to([0, 2, 0]).scale(0.5)
dot_2_text = Tex("(0,2)").scale(0.5).next_to(dot_2, UP).set_color(BLUE)
arc= ArcBetweenPoints(start=2 * RIGHT, end=2 * UP, stroke_color=YELLOW)
self.add(circle, dot_1, dot_2, dot_1_text, dot_2_text)
self.play(Create(arc))

Hemos visto anteriormente como Manim nos permite construir polígonos como cuadrados o triángulos. Podemos crear polígonos irregulares pasándole los puntos que lo componen:

poligon_example.py
from manim import *
class PolygonExample(Scene):
def construct(self):
isosceles = Polygon([-5, 1.5, 0], [-2, 1.5, 0], [-3.5, -2, 0])
position_list = [
[4, 1, 0], # middle right
[4, -2.5, 0], # bottom right
[0, -2.5, 0], # bottom left
[0, 3, 0], # top left
[2, 1, 0], # middle
[4, 3, 0], # top right
]
square_and_triangles = Polygon(*position_list, color=PURPLE_B)
self.add(isosceles, square_and_triangles)

También nos permite construir polígonos regulares tan solo especificando el número de lados necesarios.

regular_polygon_example.py
from manim import *
class RegularPolygonExample(Scene):
def construct(self):
poly_1 = RegularPolygon(n=6)
poly_2 = RegularPolygon(n=6, start_angle=30 * DEGREES, color=GREEN)
poly_3 = RegularPolygon(n=10, color=RED)
poly_group = Group(poly_1, poly_2, poly_3).scale(1.5).arrange(buff=1)
self.add(poly_group)

Con Manim también podemos crear poligramas: Figuras geométricas con forma de estrella como pentagramas:

polygram_example.py
from manim import *
class PolygramRoundCorners(Scene):
def construct(self):
star = Star(outer_radius=2)
shapes = VGroup(star)
shapes.add(star.copy().round_corners(radius=0.1))
shapes.add(star.copy().round_corners(radius=0.25))
shapes.arrange(RIGHT)
self.add(shapes)

Dentro de Manim existe un tipo de Mobject llamado TypableMobject. Se trata de objetos a los que les podemos poner puntas o tips. Un ejemplo de esto son las líneas o Line que hemos visto antes. Ade

Gracias a esto, Manim puede generar flechas con puntas de varios tipos que incluso podemos personalizar.

arrow_example.py
from manim import *
class ArrowExample(Scene):
def construct(self):
left_group = VGroup()
# As buff increases, the size of the arrow decreases.
for buff in np.arange(0, 2.2, 0.45):
left_group += Arrow(buff=buff, start=2 * LEFT, end=2 * RIGHT)
# Required to arrange arrows.
left_group.arrange(DOWN)
left_group.move_to(4 * LEFT)
middle_group = VGroup()
# As max_stroke_width_to_length_ratio gets bigger,
# the width of stroke increases.
for i in np.arange(0, 5, 0.5):
middle_group += Arrow(max_stroke_width_to_length_ratio=i)
middle_group.arrange(DOWN)
UR_group = VGroup()
# As max_tip_length_to_length_ratio increases,
# the length of the tip increases.
for i in np.arange(0, 0.3, 0.1):
UR_group += Arrow(max_tip_length_to_length_ratio=i)
UR_group.arrange(DOWN)
UR_group.move_to(4 * RIGHT + 2 * UP)
DR_group = VGroup()
DR_group += Arrow(start=LEFT, end=RIGHT, color=BLUE, tip_shape=ArrowSquareTip)
DR_group += Arrow(
start=LEFT, end=RIGHT, color=BLUE, tip_shape=ArrowSquareFilledTip
)
DR_group += Arrow(start=LEFT, end=RIGHT, color=YELLOW, tip_shape=ArrowCircleTip)
DR_group += Arrow(
start=LEFT, end=RIGHT, color=YELLOW, tip_shape=ArrowCircleFilledTip
)
DR_group.arrange(DOWN)
DR_group.move_to(4 * RIGHT + 2 * DOWN)
self.add(left_group, middle_group, UR_group, DR_group)

¡Muy bien! Ahora ya sabemos cómo poner algunos objetos en pantalla y cómo modificarlos así que propongo 3 ejercicios:

Genera una imagen con un objeto en cada esquina.

Solución al ejercicio 1
geometry_ex_1.py
from manim import *
class GeometryExerciseOne(Scene):
def construct(self):
self.add(
Square().to_corner(UL),
Circle().to_corner(UR),
Triangle().to_corner(DL),
Star(n=6).to_corner(DR),
)

Genera una imagen como la del ejercicio 1 pero esta vez cambia algunas de sus propiedades: Color, grosor, opacidad, etc.

Solución al ejercicio 2
geometry_ex_2.py
from manim import *
class GeometryExerciseTwo(Scene):
def construct(self):
self.add(
Square(color=RED).to_corner(UL),
Circle(fill_color=GOLD, fill_opacity=1).to_corner(UR),
Triangle(stroke_width=10).to_corner(DL),
Star(n=6).round_corners(radius=0.25).to_corner(DR),
)

Genera una imagen con una cantidad indefinida de objetos dispersos de forma aleatoria por la escena. Puedes poner 10, 20 o los que quieras, pero mínimo 5. Puntos extra si los objetos son variados y no siempre el mismo.

Solución al ejercicio 3
geometry_ex_3.py
from manim import *
from itertools import cycle
from random import randrange
OBJECTS_AMOUNT = 10
class GeometryExerciseThree(Scene):
def construct(self):
colors = cycle([RED, GREEN, BLUE])
m_objects = cycle([Square(), Circle(), Triangle(), Star(n=6)])
for _ in range(OBJECTS_AMOUNT):
mobject = next(m_objects).copy()
color = next(colors)
self.add(
mobject.set_color(color).move_to(
[
randrange(-60, 60, 1)/10,
randrange(-40, 40, 1)/10,
0
]
)
)