1

How to create a dashed rectangle with equally spaced dashes on both edges in manim? I've tried inheriting from Rectangle and adding dashes the same way as it is implemented for DashedLine but it produces very different densities on the longer and shorter edges. Here is my attempt (code derived from MIT licensed manim repository):

%%manim HighLevelIntuition -l -q
from manimlib_imports import *

class DashedRectangle(Rectangle):
    CONFIG = {
        "dash_length": DEFAULT_DASH_LENGTH,
        "dash_spacing": None,
        "positive_space_ratio": 0.5,
    }

    def __init__(self, *args, **kwargs):
        Rectangle.__init__(self, *args, **kwargs)
        ps_ratio = self.positive_space_ratio
        num_dashes = self.calculate_num_dashes(ps_ratio)
        dashes = DashedVMobject(
            self,
            num_dashes=num_dashes,
            positive_space_ratio=ps_ratio
        )
        self.clear_points()
        self.add(*dashes)

    def calculate_num_dashes(self, positive_space_ratio):
        try:
            full_length = self.dash_length / positive_space_ratio
            return int(np.ceil(
                self.get_arc_length() / full_length
            ))
        except ZeroDivisionError:
            return 1

class HighLevelIntuition(Scene):

    def construct(self):
        self.play(ShowCreation(DashedRectangle(width=10, height=2)))

And that's how it looks like currently:

enter image description here

FreezingFire
  • 166
  • 1
  • 8
krassowski
  • 13,598
  • 4
  • 60
  • 92
  • 1
    Also, I would love to see "manim" tag for https://github.com/3b1b/manim library - this got very popular quickly and there are already some (unfortunately not tagged) questions on SO – krassowski May 23 '19 at 17:59

1 Answers1

2

Check this:

class DashedRectangle(VGroup):
    CONFIG={
        "num_dashes": 30,
        "positive_space_ratio": 0.5,
        "width":5,
        "height":4
    }
    def __init__(self, *args, **kwargs):
        VGroup.__init__(self, *args,**kwargs)
        h1=[ORIGIN,UP*self.height]
        w1=[UP*self.height,UP*self.height+RIGHT*self.width]
        h2=[UP*self.height+RIGHT*self.width,RIGHT*self.width]
        w2=[RIGHT*self.width,ORIGIN]
        alpha=self.width/self.height
        divs=self.num_dashes

        n_h=int(divs/(2*(alpha+1)))
        n_w=int(alpha*n_h)
        dashedrectangle=VGroup()
        for n,l in zip([n_w,n_h],[[w1,w2],[h1,h2]]):
            for side in l:
                line=VMobject()
                line.set_points_as_corners(side)
                dashedrectangle.add(DashedVMobject(line,num_dashes=n,positive_space_ratio=self.positive_space_ratio))
        self.add(dashedrectangle[0],dashedrectangle[3],dashedrectangle[1],dashedrectangle[2])



class DashedRectangleScene(Scene):
    def construct(self):
        rec=DashedRectangle()
        rec.move_to(ORIGIN)
        self.play(ShowCreation(rec))
        self.wait()

DashedSquare

TheoremOfBeethoven
  • 1,864
  • 6
  • 15
  • Thank you! This is a clever workaround, though the problematic part would be that the ShowCreation() would not work as expected (each edge would be drawn independently). – krassowski May 24 '19 at 07:19
  • @krassowski Ok, try that. – TheoremOfBeethoven May 24 '19 at 08:21
  • 1
    This works great! Just because it seems that you are new to the SO - it is considered a good practice to provide some explanations and comments in addition to the code. I would even accept an answer which only points me in the right direction and allows me to develop a working solution ;) – krassowski May 24 '19 at 12:49
  • @krassowski Ok. perfect. – TheoremOfBeethoven May 24 '19 at 18:30