Repository: ManimCommunity/manim
File: manim/utils/bezier.py (Python)

Code before:
    ------
    :class:`ValueError`
        When ``point`` and the control points have different shapes.
    """
    if not all(np.shape(point) == np.shape(c_p) for c_p in control_points):
        raise ValueError(
            f"Point {point} and Control Points {control_points} have different shapes."
        )
    control_points = np.array(control_points)
    n = len(control_points) - 1

    roots = []
    for dim, coord in enumerate(point):
        control_coords = c_c = control_points[:, dim]
        terms = []
        for term_power in range(n, -1, -1):
            outercoeff = choose(n, term_power)
            term = []
            negative = 1
            for subterm_num in range(term_power, -1, -1):
                innercoeff = choose(term_power, subterm_num) * negative
                subterm = (
                    innercoeff * c_c[subterm_num]
                    if term_power > 0
                    else ((innercoeff * c_c[subterm_num]) - coord)
                )
                term.append(subterm)
                negative = -1 if negative > 0 else 1
            terms.append(outercoeff * sum(np.array(term)))
        bezier_polynom = np.polynomial.Polynomial(terms[::-1])
        polynom_roots = bezier_polynom.roots()
        if len(polynom_roots) > 0:
            roots.append(polynom_roots)

    roots = np.around(roots, int(np.log10(1 / round_to)))
    roots = [[root for root in rootlist if root.imag == 0] for rootlist in roots]
    roots = reduce(np.intersect1d, roots)  # Get common roots.
    roots = np.array([r.real for r in roots]).tolist()
    return roots


def point_lies_on_bezier(
    point: typing.Iterable[typing.Union[float, int]],
    control_points: typing.Iterable[typing.Iterable[typing.Union[float, int]]],
    round_to: typing.Optional[typing.Union[float, int]] = 1e-6,
) -> bool:
    """Checks if a given point lies on the bezier curves with the given control points.

    Parameters
    ----------
    point

Review comment (suggestion):
```suggestion
                subterm = innercoeff * c_c[subterm_num]
                if term_power == 0:
                    subterm -= coord
```

Code after:
            end etc. of the loop.

    Raises
    ------
    :class:`ValueError`
        When ``point`` and the control points have different shapes.
    """
    # Method taken from
    # http://polymathprogrammer.com/2012/04/03/does-point-lie-on-bezier-curve/

    if not all(np.shape(point) == np.shape(c_p) for c_p in control_points):
        raise ValueError(
            f"Point {point} and Control Points {control_points} have different shapes."
        )

    control_points = np.array(control_points)
    n = len(control_points) - 1

    roots = []
    for dim, coord in enumerate(point):
        control_coords = control_points[:, dim]
        terms = []
        for term_power in range(n, -1, -1):
            outercoeff = choose(n, term_power)
            term = []
            sign = 1
            for subterm_num in range(term_power, -1, -1):
                innercoeff = choose(term_power, subterm_num) * sign
                subterm = innercoeff * control_coords[subterm_num]
                if term_power == 0:
                    subterm -= coord
                term.append(subterm)
                sign *= -1
            terms.append(outercoeff * sum(np.array(term)))
        if all(term == 0 for term in terms):
            # Then both Bezier curve and Point lie on the same plane.
            # Roots will be none, but in this specific instance, we don't need to consider that.
            continue
        bezier_polynom = np.polynomial.Polynomial(terms[::-1])
        polynom_roots = bezier_polynom.roots()
        if len(polynom_roots) > 0:
            polynom_roots = np.around(polynom_roots, int(np.log10(1 / round_to)))
        roots.append(polynom_roots)

    roots = [[root for root in rootlist if root.imag == 0] for rootlist in roots]
    roots = reduce(np.intersect1d, roots)  # Get common roots.
    roots = np.array([r.real for r in roots])
    return roots


def point_lies_on_bezier(