Files
ManimML/manim_ml/gridded_rectangle.py

137 lines
4.5 KiB
Python

from manim import *
import numpy as np
class GriddedRectangle(VGroup):
"""Rectangle object with grid lines"""
def __init__(
self,
color=ORANGE,
height=2.0,
width=4.0,
mark_paths_closed=True,
close_new_points=True,
grid_xstep=None,
grid_ystep=None,
grid_stroke_width=0.0, # DEFAULT_STROKE_WIDTH/2,
grid_stroke_color=ORANGE,
grid_stroke_opacity=1.0,
stroke_width=2.0,
fill_opacity=0.2,
show_grid_lines=False,
**kwargs
):
super().__init__()
# Fields
self.color = color
self.mark_paths_closed = mark_paths_closed
self.close_new_points = close_new_points
self.grid_xstep = grid_xstep
self.grid_ystep = grid_ystep
self.grid_stroke_width = grid_stroke_width
self.grid_stroke_color = grid_stroke_color
self.grid_stroke_opacity = grid_stroke_opacity if show_grid_lines else 0.0
self.stroke_width = stroke_width
self.rotation_angles = [0, 0, 0]
self.show_grid_lines = show_grid_lines
# Make rectangle
self.rectangle = Rectangle(
width=width,
height=height,
color=color,
stroke_width=stroke_width,
fill_color=color,
fill_opacity=fill_opacity,
)
self.add(self.rectangle)
# Make grid lines
grid_lines = self.make_grid_lines()
self.add(grid_lines)
# Make corner rectangles
self.corners_dict = self.make_corners_dict()
self.add(*self.corners_dict.values())
def make_corners_dict(self):
"""Make corners dictionary"""
corners_dict = {
"top_right": Dot(
self.rectangle.get_corner([1, 1, 0]), fill_opacity=0.0, radius=0.0
),
"top_left": Dot(
self.rectangle.get_corner([-1, 1, 0]), fill_opacity=0.0, radius=0.0
),
"bottom_left": Dot(
self.rectangle.get_corner([-1, -1, 0]), fill_opacity=0.0, radius=0.0
),
"bottom_right": Dot(
self.rectangle.get_corner([1, -1, 0]), fill_opacity=0.0, radius=0.0
),
}
return corners_dict
def get_corners_dict(self):
"""Returns a dictionary of the corners"""
# Sort points through clockwise rotation of a vector in the xy plane
return self.corners_dict
def make_grid_lines(self):
"""Make grid lines in rectangle"""
grid_lines = VGroup()
v = self.rectangle.get_vertices()
if self.grid_xstep is not None:
grid_xstep = abs(self.grid_xstep)
count = int(self.width / grid_xstep)
grid = VGroup(
*(
Line(
v[1] + i * grid_xstep * RIGHT,
v[1] + i * grid_xstep * RIGHT + self.height * DOWN,
stroke_color=self.grid_stroke_color,
stroke_width=self.grid_stroke_width,
stroke_opacity=self.grid_stroke_opacity,
)
for i in range(1, count)
)
)
grid_lines.add(grid)
if self.grid_ystep is not None:
grid_ystep = abs(self.grid_ystep)
count = int(self.height / grid_ystep)
grid = VGroup(
*(
Line(
v[1] + i * grid_ystep * DOWN,
v[1] + i * grid_ystep * DOWN + self.width * RIGHT,
stroke_color=self.grid_stroke_color,
stroke_width=self.grid_stroke_width,
stroke_opacity=self.grid_stroke_opacity,
)
for i in range(1, count)
)
)
grid_lines.add(grid)
return grid_lines
def get_center(self):
return self.rectangle.get_center()
def get_normal_vector(self):
vertex_1 = self.rectangle.get_vertices()[0]
vertex_2 = self.rectangle.get_vertices()[1]
vertex_3 = self.rectangle.get_vertices()[2]
# First vector
normal_vector = np.cross((vertex_1 - vertex_2), (vertex_1 - vertex_3))
return normal_vector
def set_color(self, color):
"""Sets the color of the gridded rectangle"""
self.color = color
self.rectangle.set_color(color)
self.rectangle.set_stroke_color(color)