From 7aba7c58ea43c63b5202da90a4cb2bec35fe0a0a Mon Sep 17 00:00:00 2001 From: cclauss Date: Fri, 16 Feb 2018 15:12:14 +0100 Subject: [PATCH 1/3] Manim depends on Python 2.7 and is not yet compatible with Python 3. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 946a8d5f..8ca54e13 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ For 9/10 math animation needs, you'd probably be better off using a more well-ma ## Install requirements +Manim depends on Python 2.7 and is not yet compatible with Python 3. + Manim dependencies rely on system libraries you will need to install on your operating system: * ffmpeg From c43915b3197c38516a801752af80b492fe638ba2 Mon Sep 17 00:00:00 2001 From: Dan Waxman Date: Sun, 25 Mar 2018 16:21:56 -0400 Subject: [PATCH 2/3] Fixed DoubleArrow Scaling Previously, only one tip was kept as self.tip and was scaled properly. This meant the first part of the solutionw as to create a list of all tips. After this, the issue was that draw_at_end defaults to True, and is not preserved. So the list is now a tuple of the tip VMobject and its add_at_end property. Since these should be identifical except for position, everything that asked for a property from tip now asks for the same property from the first tip. This isn't pretty, but it should fix the problem. --- topics/geometry.py | 52 +++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/topics/geometry.py b/topics/geometry.py index 00475e8d..b602b474 100644 --- a/topics/geometry.py +++ b/topics/geometry.py @@ -18,8 +18,8 @@ class Arc(VMobject): anchors = np.array([ np.cos(a)*RIGHT+np.sin(a)*UP for a in np.linspace( - self.start_angle, - self.start_angle + self.angle, + self.start_angle, + self.start_angle + self.angle, self.num_anchors ) ]) @@ -49,7 +49,7 @@ class Arc(VMobject): p1, p2 = self.points[-3:-1] # self.points[-2:] did overshoot start_arrow = Arrow( - p1, 2*p2 - p1, + p1, 2*p2 - p1, tip_length = tip_length, max_tip_length_to_length_ratio = 2.0 ) @@ -59,16 +59,16 @@ class Arc(VMobject): p4, p3 = self.points[1:3] # self.points[:2] did overshoot end_arrow = Arrow( - p3, 2*p4 - p3, + p3, 2*p4 - p3, tip_length = tip_length, max_tip_length_to_length_ratio = 2.0 ) self.add(end_arrow.split()[-1]) - - + + self.highlight(self.get_color()) return self @@ -93,7 +93,7 @@ class Arc(VMobject): def set_bound_angles(self,start=0,stop=np.pi): self.start_angle = start self.angle = stop - start - + return self @@ -125,7 +125,7 @@ class ArcBetweenPoints(Arc): radius = radius, start_angle = start_angle, **kwargs) - + self.move_arc_center_to(arc_center) class CurvedArrow(ArcBetweenPoints): @@ -138,7 +138,7 @@ class CurvedArrow(ArcBetweenPoints): else: ArcBetweenPoints.__init__(self, end_point, start_point, angle = -angle, **kwargs) self.add_tip(at_start = False, at_end = True) - + class CurvedDoubleArrow(ArcBetweenPoints): @@ -476,7 +476,7 @@ class Arrow(Line): self.init_colors() def init_tip(self): - self.tip = self.add_tip() + self.add_tip() def add_tip(self, add_at_end = True): tip = VMobject( @@ -489,13 +489,16 @@ class Arrow(Line): ) self.set_tip_points(tip, add_at_end, preserve_normal = False) self.add(tip) + if not hasattr(self, 'tip'): + self.tip = [] + self.tip.append(tuple((tip, add_at_end))) return tip def add_rectangular_stem(self): self.rect = Rectangle( stroke_width = 0, - fill_color = self.tip.get_fill_color(), - fill_opacity = self.tip.get_fill_opacity() + fill_color = self.tip[0][0].get_fill_color(), + fill_opacity = self.tip[0][0].get_fill_opacity() ) self.add_to_back(self.rect) self.set_stroke(width = 0) @@ -504,7 +507,7 @@ class Arrow(Line): def set_rectangular_stem_points(self): start, end = self.get_start_and_end() vect = end - start - tip_base_points = self.tip.get_anchors()[1:] + tip_base_points = self.tip[0][0].get_anchors()[1:] tip_base = center_of_mass(tip_base_points) tbp1, tbp2 = tip_base_points perp_vect = tbp2 - tbp1 @@ -528,8 +531,8 @@ class Arrow(Line): return self def set_tip_points( - self, tip, - add_at_end = True, + self, tip, + add_at_end = True, tip_length = None, preserve_normal = True, ): @@ -557,7 +560,7 @@ class Arrow(Line): v *= tip_length/np.linalg.norm(v) ratio = self.tip_width_to_length_ratio tip.set_points_as_corners([ - end_point, + end_point, end_point-vect+perp_vect*ratio/2, end_point-vect-perp_vect*ratio/2, ]) @@ -565,7 +568,7 @@ class Arrow(Line): return self def get_normal_vector(self): - p0, p1, p2 = self.tip.get_anchors() + p0, p1, p2 = self.tip[0][0].get_anchors() result = np.cross(p2 - p1, p1 - p0) norm = np.linalg.norm(result) if norm == 0: @@ -579,7 +582,7 @@ class Arrow(Line): def get_end(self): if hasattr(self, "tip"): - return self.tip.get_anchors()[0] + return self.tip[0][0].get_anchors()[0] else: return Line.get_end(self) @@ -588,14 +591,16 @@ class Arrow(Line): def put_start_and_end_on(self, *args, **kwargs): Line.put_start_and_end_on(self, *args, **kwargs) - self.set_tip_points(self.tip, preserve_normal = False) + self.set_tip_points(self.tip[0][0], preserve_normal = False) self.set_rectangular_stem_points() return self def scale(self, scale_factor, **kwargs): Line.scale(self, scale_factor, **kwargs) if self.preserve_tip_size_when_scaling: - self.set_tip_points(self.tip) + for t in self.tip: + print(t) + self.set_tip_points(t[0], add_at_end=t[1]) if self.use_rectangular_stem: self.set_rectangular_stem_points() return self @@ -615,8 +620,7 @@ class Vector(Arrow): class DoubleArrow(Arrow): def init_tip(self): - self.tip = self.add_tip() - self.second_tip = self.add_tip(add_at_end = False) + self.tip = [(self.add_tip(), True), (self.add_tip(add_at_end = False), False)] class CubicBezier(VMobject): def __init__(self, points, **kwargs): @@ -674,7 +678,7 @@ class Square(Rectangle): def __init__(self, **kwargs): digest_config(self, kwargs) Rectangle.__init__( - self, + self, height = self.side_length, width = self.side_length, **kwargs @@ -755,7 +759,7 @@ class Cross(VGroup): "stroke_width" : 6, } def __init__(self, mobject, **kwargs): - VGroup.__init__(self, + VGroup.__init__(self, Line(UP+LEFT, DOWN+RIGHT), Line(UP+RIGHT, DOWN+LEFT), ) From 28193b54b382951c45a3e6d8526872a9ba485cd5 Mon Sep 17 00:00:00 2001 From: Grant Sanderson Date: Sun, 1 Apr 2018 11:05:24 -0700 Subject: [PATCH 3/3] geometry.py updates --- topics/geometry.py | 133 ++++++++++----------------------------------- 1 file changed, 28 insertions(+), 105 deletions(-) diff --git a/topics/geometry.py b/topics/geometry.py index 81ca1316..e7fc63d1 100644 --- a/topics/geometry.py +++ b/topics/geometry.py @@ -25,8 +25,8 @@ class Arc(VMobject): anchors = np.array([ np.cos(a)*RIGHT+np.sin(a)*UP for a in np.linspace( - self.start_angle, - self.start_angle + self.angle, + self.start_angle, + self.start_angle + self.angle, self.num_anchors ) ]) @@ -56,7 +56,7 @@ class Arc(VMobject): p1, p2 = self.points[-3:-1] # self.points[-2:] did overshoot start_arrow = Arrow( - p1, 2*p2 - p1, + p1, 2*p2 - p1, tip_length = tip_length, max_tip_length_to_length_ratio = 2.0 ) @@ -66,12 +66,16 @@ class Arc(VMobject): p4, p3 = self.points[1:3] # self.points[:2] did overshoot end_arrow = Arrow( - p3, 2*p4 - p3, + p3, 2*p4 - p3, tip_length = tip_length, max_tip_length_to_length_ratio = 2.0 ) self.add(end_arrow.split()[-1]) + + + + self.set_color(self.get_color()) return self @@ -96,11 +100,9 @@ class Arc(VMobject): def set_bound_angles(self,start=0,stop=np.pi): self.start_angle = start self.angle = stop - start - + return self - - class ArcBetweenPoints(Arc): def __init__(self, start_point, end_point, angle = TAU/4, **kwargs): @@ -128,7 +130,7 @@ class ArcBetweenPoints(Arc): radius = radius, start_angle = start_angle, **kwargs) - + self.move_arc_center_to(arc_center) class CurvedArrow(ArcBetweenPoints): @@ -142,14 +144,12 @@ class CurvedArrow(ArcBetweenPoints): ArcBetweenPoints.__init__(self, end_point, start_point, angle = -angle, **kwargs) self.add_tip(at_start = False, at_end = True) - class CurvedDoubleArrow(ArcBetweenPoints): def __init__(self, start_point, end_point, angle = TAU/4, **kwargs): ArcBetweenPoints.__init__(self, start_point, end_point, angle = angle, **kwargs) self.add_tip(at_start = True, at_end = True) - class Circle(Arc): CONFIG = { "color" : RED, @@ -490,18 +490,20 @@ class Arrow(Line): stroke_color = self.color, stroke_width = 0, ) + tip.add_at_end = add_at_end self.set_tip_points(tip, add_at_end, preserve_normal = False) self.add(tip) if not hasattr(self, 'tip'): - self.tip = [] - self.tip.append(tuple((tip, add_at_end))) + self.tip = VGroup() + self.tip.match_style(tip) + self.tip.add(tip) return tip def add_rectangular_stem(self): self.rect = Rectangle( stroke_width = 0, - fill_color = self.tip[0][0].get_fill_color(), - fill_opacity = self.tip[0][0].get_fill_opacity() + fill_color = self.tip.get_fill_color(), + fill_opacity = self.tip.get_fill_opacity() ) self.add_to_back(self.rect) self.set_stroke(width = 0) @@ -510,7 +512,7 @@ class Arrow(Line): def set_rectangular_stem_points(self): start, end = self.get_start_and_end() vect = end - start - tip_base_points = self.tip[0][0].get_anchors()[1:] + tip_base_points = self.tip[0].get_anchors()[1:] tip_base = center_of_mass(tip_base_points) tbp1, tbp2 = tip_base_points perp_vect = tbp2 - tbp1 @@ -571,7 +573,7 @@ class Arrow(Line): return self def get_normal_vector(self): - p0, p1, p2 = self.tip[0][0].get_anchors() + p0, p1, p2 = self.tip[0].get_anchors() result = np.cross(p2 - p1, p1 - p0) norm = np.linalg.norm(result) if norm == 0: @@ -585,7 +587,7 @@ class Arrow(Line): def get_end(self): if hasattr(self, "tip"): - return self.tip[0][0].get_anchors()[0] + return self.tip[0].get_anchors()[0] else: return Line.get_end(self) @@ -594,7 +596,7 @@ class Arrow(Line): def put_start_and_end_on(self, *args, **kwargs): Line.put_start_and_end_on(self, *args, **kwargs) - self.set_tip_points(self.tip[0][0], preserve_normal = False) + self.set_tip_points(self.tip[0], preserve_normal = False) self.set_rectangular_stem_points() return self @@ -602,8 +604,7 @@ class Arrow(Line): Line.scale(self, scale_factor, **kwargs) if self.preserve_tip_size_when_scaling: for t in self.tip: - print(t) - self.set_tip_points(t[0], add_at_end=t[1]) + self.set_tip_points(t, add_at_end=t.add_at_end) if self.use_rectangular_stem: self.set_rectangular_stem_points() return self @@ -623,7 +624,12 @@ class Vector(Arrow): class DoubleArrow(Arrow): def init_tip(self): - self.tip = [(self.add_tip(), True), (self.add_tip(add_at_end = False), False)] + self.tip = VGroup() + for b in True, False: + t = self.add_tip(add_at_end = b) + t.add_at_end = b + self.tip.add(t) + self.tip.match_style(self.tip[0]) class CubicBezier(VMobject): def __init__(self, points, **kwargs): @@ -681,94 +687,12 @@ class Square(Rectangle): def __init__(self, **kwargs): digest_config(self, kwargs) Rectangle.__init__( - self, + self, height = self.side_length, width = self.side_length, **kwargs ) -class SurroundingRectangle(Rectangle): - CONFIG = { - "color" : YELLOW, - "buff" : SMALL_BUFF, - } - def __init__(self, mobject, **kwargs): - digest_config(self, kwargs) - kwargs["width"] = mobject.get_width() + 2*self.buff - kwargs["height"] = mobject.get_height() + 2*self.buff - Rectangle.__init__(self, **kwargs) - self.move_to(mobject) - -class BackgroundRectangle(SurroundingRectangle): - CONFIG = { - "color" : BLACK, - "stroke_width" : 0, - "fill_opacity" : 0.75, - "buff" : 0 - } - def __init__(self, mobject, **kwargs): - SurroundingRectangle.__init__(self, mobject, **kwargs) - self.original_fill_opacity = self.fill_opacity - - def pointwise_become_partial(self, mobject, a, b): - self.set_fill(opacity = b*self.original_fill_opacity) - return self - - def get_fill_color(self): - return Color(self.color) - -class ScreenRectangle(Rectangle): - CONFIG = { - "width_to_height_ratio" : 16.0/9.0, - "height" : 4, - } - def generate_points(self): - self.width = self.width_to_height_ratio * self.height - Rectangle.generate_points(self) - -class FullScreenRectangle(ScreenRectangle): - CONFIG = { - "height" : FRAME_HEIGHT, - } - -class FullScreenFadeRectangle(FullScreenRectangle): - CONFIG = { - "stroke_width" : 0, - "fill_color" : BLACK, - "fill_opacity" : 0.7, - } - -class PictureInPictureFrame(Rectangle): - CONFIG = { - "height" : 3, - "aspect_ratio" : (16, 9) - } - def __init__(self, **kwargs): - digest_config(self, kwargs) - height = self.height - if "height" in kwargs: - kwargs.pop("height") - Rectangle.__init__( - self, - width = self.aspect_ratio[0], - height = self.aspect_ratio[1], - **kwargs - ) - self.scale_to_fit_height(height) - -class Cross(VGroup): - CONFIG = { - "stroke_color" : RED, - "stroke_width" : 6, - } - def __init__(self, mobject, **kwargs): - VGroup.__init__(self, - Line(UP+LEFT, DOWN+RIGHT), - Line(UP+RIGHT, DOWN+LEFT), - ) - self.replace(mobject, stretch = True) - self.set_stroke(self.stroke_color, self.stroke_width) - class Grid(VMobject): CONFIG = { "height" : 6.0, @@ -794,4 +718,3 @@ class Grid(VMobject): )) -