diff --git a/manimlib/mobject/functions.py b/manimlib/mobject/functions.py index 6d55b395..adc9c455 100644 --- a/manimlib/mobject/functions.py +++ b/manimlib/mobject/functions.py @@ -11,38 +11,30 @@ from manimlib.utils.config_ops import digest_config from typing import TYPE_CHECKING if TYPE_CHECKING: - from typing import Callable, Sequence + from typing import Callable, Sequence, Tuple + from manimlib.constants import ManimColor, np_vector class ParametricCurve(VMobject): - CONFIG = { - "t_range": [0, 1, 0.1], - "epsilon": 1e-8, - # TODO, automatically figure out discontinuities - "discontinuities": [], - "use_smoothing": True, - } - def __init__( self, - t_func: Callable[[float], np.ndarray], - t_range: Sequence[float] | None = None, + t_func: Callable[[float], Sequence[float]], + t_range: Tuple[float, float, float] = (0, 1, 0.1), + epsilon: float = 1e-8, + # TODO, automatically figure out discontinuities + discontinuities: Sequence[float] = [], + use_smoothing: bool = True, **kwargs ): - digest_config(self, kwargs) - if t_range is not None: - self.t_range[:len(t_range)] = t_range - # To be backward compatible with all the scenes specifying t_min, t_max, step_size - self.t_range = [ - kwargs.get("t_min", self.t_range[0]), - kwargs.get("t_max", self.t_range[1]), - kwargs.get("step_size", self.t_range[2]), - ] self.t_func = t_func - VMobject.__init__(self, **kwargs) + self.t_range = t_range + self.epsilon = epsilon + self.discontinuities = discontinuities + self.use_smoothing = use_smoothing + super().__init__(**kwargs) - def get_point_from_function(self, t: float) -> np.ndarray: - return self.t_func(t) + def get_point_from_function(self, t: float) -> np_vector: + return np.array(self.t_func(t)) def init_points(self): t_min, t_max, step = self.t_range @@ -59,7 +51,7 @@ class ParametricCurve(VMobject): if self.use_smoothing: self.make_approximately_smooth() if not self.has_points(): - self.set_points([self.t_func(t_min)]) + self.set_points(np.array([self.t_func(t_min)])) return self def get_t_func(self): @@ -77,22 +69,15 @@ class ParametricCurve(VMobject): class FunctionGraph(ParametricCurve): - CONFIG = { - "color": YELLOW, - "x_range": [-8, 8, 0.25], - } - def __init__( self, function: Callable[[float], float], - x_range: Sequence[float] | None = None, + x_range: Tuple[float, float, float] = (-8, 8, 0.25), + color: ManimColor = YELLOW, **kwargs ): - digest_config(self, kwargs) self.function = function - - if x_range is not None: - self.x_range[:len(x_range)] = x_range + self.x_range = x_range def parametric_function(t): return [t, function(t), 0] @@ -101,34 +86,28 @@ class FunctionGraph(ParametricCurve): class ImplicitFunction(VMobject): - CONFIG = { - "x_range": [-FRAME_X_RADIUS, FRAME_X_RADIUS], - "y_range": [-FRAME_Y_RADIUS, FRAME_Y_RADIUS], - "min_depth": 5, - "max_quads": 1500, - "use_smoothing": True - } - def __init__( self, func: Callable[[float, float], float], + x_range: Tuple[float, float] = (-FRAME_X_RADIUS, FRAME_X_RADIUS), + y_range: Tuple[float, float] = (-FRAME_Y_RADIUS, FRAME_Y_RADIUS), + min_depth: int = 5, + max_quads: int = 1500, + use_smoothing: bool = True, **kwargs ): - digest_config(self, kwargs) - self.function = func super().__init__(**kwargs) - def init_points(self): p_min, p_max = ( - np.array([self.x_range[0], self.y_range[0]]), - np.array([self.x_range[1], self.y_range[1]]), + np.array([x_range[0], y_range[0]]), + np.array([x_range[1], y_range[1]]), ) curves = plot_isoline( - fn=lambda u: self.function(u[0], u[1]), + fn=lambda u: func(u[0], u[1]), pmin=p_min, pmax=p_max, - min_depth=self.min_depth, - max_quads=self.max_quads, + min_depth=min_depth, + max_quads=max_quads, ) # returns a list of lists of 2D points curves = [ np.pad(curve, [(0, 0), (0, 1)]) for curve in curves if curve != [] @@ -136,6 +115,5 @@ class ImplicitFunction(VMobject): for curve in curves: self.start_new_path(curve[0]) self.add_points_as_corners(curve[1:]) - if self.use_smoothing: + if use_smoothing: self.make_smooth() - return self