Search code examples
manim

How to determine the edge center of a polygon


I use a polygon to make a triangle:

tri1 = Polygon(LEFT*1.5+UP, RIGHT*1.5+UP, RIGHT*1.5+UP*1.5)

Then I want to show three texts in the edge center of the polygon.

c = TexMobject("c").next_to(tri1.get_edge_center(LEFT), UP)
a = TexMobject("a").next_to(tri1.get_edge_center(DOWN), DOWN)
b = TexMobject("b").next_to(tri1.get_edge_center(RIGHT), RIGHT)

However the "c" is far away the edge center, so I change the position from:

tri1.get_edge_center(LEFT)

to

interpolate(LEFT*1.5+UP, RIGHT*1.5+UP*1.5, 0.5)

it looks ok. However I want to use a consistent way to do this, How to get position for "c" using get_edge_center? Thanks!


Solution

  • If you check the manimlib / mobject.py library or the vector_mobject library you will see that there is no such similar. One of the things that makes manim so cool is that if something can't be done, you can do it yourself. I recommend that instead of asking, if you don't find a method, you create it yourself (like the interpolate thing). In this way you will learn more and develop your own code without depending on what you can or cannot do.

    class Polygon(Polygon):
        def get_center_of_edges(self,buff=SMALL_BUFF*3):
            vertices = self.get_vertices()
            coords_vertices = []
            for i in range(len(vertices)):
                if i < len(vertices)-1:
                    p1,p2 = [vertices[i],vertices[i+1]]
                else:
                    p1,p2 = [vertices[-1],vertices[0]]
                guide_line = Line(p1,p2)
                side = guide_line.get_center()
                normal_direction = guide_line.copy()
                normal_direction.rotate(-PI/2)
                vector_normal_direction = normal_direction.get_unit_vector()
                direction = Dot(side).shift(vector_normal_direction*buff).get_center()
                coords_vertices.append(direction)
    
            return coords_vertices
    
    
    class PolygonScene(Scene):
        def construct(self):
            tri1 = Polygon(LEFT*1.5+UP, RIGHT*1.5+UP, RIGHT*1.5+UP*1.5)
            center_vertices =tri1.get_center_of_edges()
            labels = VGroup(*[
                TexMobject(label).move_to(point) for label,point in zip(["a","b","c"],center_vertices)
                ])
    
            self.add(tri1,labels)
    

    enter image description here

    class RegularPolygon(RegularPolygon):
        def get_center_of_edges(self,buff=SMALL_BUFF*3):
            vertices = self.get_vertices()
            coords_vertices = []
            for i in range(len(vertices)):
                if i < len(vertices)-1:
                    p1,p2 = [vertices[i],vertices[i+1]]
                else:
                    p1,p2 = [vertices[-1],vertices[0]]
                guide_line = Line(p1,p2)
                side = guide_line.get_center()
                normal_direction = guide_line.copy()
                normal_direction.rotate(-PI/2)
                vector_normal_direction = normal_direction.get_unit_vector()
                direction = Dot(side).shift(vector_normal_direction*buff).get_center()
                coords_vertices.append(direction)
    
            return coords_vertices
    
    
    class PolygonScene2(Scene):
        def construct(self):
            tri1 = RegularPolygon(6).scale(2.5)
            center_vertices =tri1.get_center_of_edges()
            labels = ["a","b","c","d","e","f"]
            labels = VGroup(*[
                TexMobject(label).move_to(point) for label,point in zip(labels,center_vertices)
                ])
    
            self.add(tri1,labels)
    

    enter image description here