# This file is automatically generated by pyo3_stub_gen
# ruff: noqa: E501, F401, F403, F405
r"""
Cubic bezier curve queries and conversions.

Provides point evaluation at a parameter t, splitting into two halves,
bounding rectangle computation, flattening to line segments (both
fixed-step and adaptive subdivision), rectangle clipping, flatness
testing, perpendicular distance measurement, and conversion from
cubic to quadratic form.
"""

from raygeo.geo import types
import typing
__all__ = [
    "clip_bezier_with_rect",
    "convert_cubic_bezier_to_quadratic",
    "fit_cubic_bezier",
    "flatten_bezier",
    "get_bezier_bounds",
    "get_bezier_flatness_sq",
    "get_bezier_length",
    "get_bezier_point_at",
    "get_bezier_rect_intersections",
    "get_perpendicular_dist_sq",
    "is_bezier_flat",
    "is_bezier_inside_polygons",
    "linearize_bezier",
    "linearize_bezier_adaptive",
    "linearize_bezier_segment",
    "nearest_tangent_circle_on_bezier",
    "split_bezier",
]

def clip_bezier_with_rect(p0: types.Point, p1: types.Point, p2: types.Point, p3: types.Point, rect: types.Rect) -> list[tuple[types.Point, types.Point, types.Point, types.Point]]:
    r"""
    Clip a cubic bezier with a rectangle.
    
    :param p0: Start control point (x, y).
    :param p1: First control point (x, y).
    :param p2: Second control point (x, y).
    :param p3: End control point (x, y).
    :param rect: Clipping rectangle (x_min, y_min, x_max, y_max).
    :returns: List of bezier segments inside the rectangle.
    :complexity: O(n)
    """

def convert_cubic_bezier_to_quadratic(p0: types.Point, p1: types.Point, p2: types.Point, p3: types.Point) -> tuple[types.Point, types.Point, types.Point]:
    r"""
    Convert a cubic bezier to a quadratic bezier.
    
    :param p0: Start control point (x, y).
    :param p1: First control point (x, y).
    :param p2: Second control point (x, y).
    :param p3: End control point (x, y).
    :returns: Quadratic bezier (p0, p1, p2).
    :complexity: O(1)
    """

def fit_cubic_bezier(points: list[tuple[float, float]]) -> typing.Optional[types.CubicBezier]:
    r"""
    Fit a cubic Bezier curve to a sequence of points (least-squares).
    
    :param points: List of (x, y) points.
    :returns: ``(p0, c1, c2, p3)`` or None if fewer than 2 points.
    """

def flatten_bezier(p0: types.Point3D, p1: types.Point3D, p2: types.Point3D, p3: types.Point3D, tolerance: float, max_subdivisions: int, pts: list) -> None:
    r"""
    Flatten a bezier curve into points.
    
    :param p0: Start control point (x, y, z).
    :param p1: First control point (x, y, z).
    :param p2: Second control point (x, y, z).
    :param p3: End control point (x, y, z).
    :param tolerance: Flattening tolerance.
    :param max_subdivisions: Maximum recursion depth.
    :param pts: Output list to append points to.
    :returns: List of ``(x, y)`` points along the flattened bezier.
    :complexity: O(n)
    """

def get_bezier_bounds(p0: types.Point, p1: types.Point, p2: types.Point, p3: types.Point) -> types.Rect:
    r"""
    Get the bounding rectangle of a cubic bezier.
    
    :param p0: Start control point (x, y).
    :param p1: First control point (x, y).
    :param p2: Second control point (x, y).
    :param p3: End control point (x, y).
    :returns: Bounding rectangle as (x_min, y_min, x_max, y_max).
    :complexity: O(1)
    """

def get_bezier_flatness_sq(a: types.Point3D, b: types.Point3D, c: types.Point3D, d: types.Point3D) -> float:
    r"""
    Compute the flatness squared of a cubic bezier.
    
    :param a: Start point (x, y, z).
    :param b: First control point (x, y, z).
    :param c: Second control point (x, y, z).
    :param d: End point (x, y, z).
    :returns: Flatness squared value.
    :complexity: O(1)
    """

def get_bezier_length(p0: types.Point, c1: types.Point, c2: types.Point, p1: types.Point) -> float:
    r"""
    Compute the arc length of a cubic Bezier curve.
    
    :param p0: Start point (x, y).
    :param c1: First control point (x, y).
    :param c2: Second control point (x, y).
    :param p1: End point (x, y).
    :returns: Arc length.
    :complexity: O(n)
    """

def get_bezier_point_at(p0: types.Point, p1: types.Point, p2: types.Point, p3: types.Point, t: float) -> types.Point:
    r"""
    Get a point on a cubic bezier at parameter t.
    
    :param p0: Start control point (x, y).
    :param p1: First control point (x, y).
    :param p2: Second control point (x, y).
    :param p3: End control point (x, y).
    :param t: Parameter value (0..1).
    :returns: Point on the bezier curve (x, y).
    :complexity: O(1)
    """

def get_bezier_rect_intersections(p0: types.Point, p1: types.Point, p2: types.Point, p3: types.Point, rect: types.Rect) -> list[float]:
    r"""
    Get intersection t-values of a bezier with a rectangle.
    
    :param p0: Start control point (x, y).
    :param p1: First control point (x, y).
    :param p2: Second control point (x, y).
    :param p3: End control point (x, y).
    :param rect: Rectangle (x_min, y_min, x_max, y_max).
    :returns: List of t-values where the bezier intersects.
    :complexity: O(n)
    """

def get_perpendicular_dist_sq(pt: types.Point3D, origin: types.Point3D, vx: float, vy: float, vz: float = 0, norm_sq: float = 0) -> float:
    r"""
    Compute the perpendicular distance squared.
    
    :param pt: Point to measure from.
    :param origin: Origin of the line.
    :param vx: X component of line direction.
    :param vy: Y component of line direction.
    :param vz: Z component of line direction.
    :param norm_sq: Precomputed squared norm (optional).
    :returns: Perpendicular distance squared.
    :complexity: O(1)
    """

def is_bezier_flat(p0: types.Point, p1: types.Point, p2: types.Point, p3: types.Point, tolerance_sq: float) -> bool:
    r"""
    Test whether a cubic bezier curve is flat enough to approximate with a line segment.
    
    Uses a chord-distance flatness test. For non-degenerate curves (p0 != p3)
    it checks whether both control points lie within tolerance_sq of the chord
    line. For degenerate curves (p0 approx p3) it checks the control point
    distances from the start point.
    
    :param p0: Start control point (x, y).
    :param p1: First control point (x, y).
    :param p2: Second control point (x, y).
    :param p3: End control point (x, y).
    :param tolerance_sq: Squared tolerance for flatness.
    :returns: True if the curve is flat enough.
    :complexity: O(1)
    """

def is_bezier_inside_polygons(p0: types.Point, p1: types.Point, p2: types.Point, p3: types.Point, polygons: typing.Any) -> bool:
    r"""
    Check if a bezier curve is inside a set of polygons.
    
    :param p0: Start control point (x, y).
    :param p1: First control point (x, y).
    :param p2: Second control point (x, y).
    :param p3: End control point (x, y).
    :param polygons: List of polygons to check against.
    :returns: True if the bezier is inside all polygons.
    :complexity: O(n * m)
    """

def linearize_bezier(p0: types.Point3D, p1: types.Point3D, p2: types.Point3D, p3: types.Point3D, num_steps: int) -> list[tuple[types.Point3D, types.Point3D]]:
    r"""
    Linearize a bezier into line segments.
    
    :param p0: Start control point (x, y, z).
    :param p1: First control point (x, y, z).
    :param p2: Second control point (x, y, z).
    :param p3: End control point (x, y, z).
    :param num_steps: Number of linearization steps.
    :returns: List of (p1, p2) segment pairs.
    :complexity: O(n)
    """

def linearize_bezier_adaptive(p0: types.Point, p1: types.Point, p2: types.Point, p3: types.Point, tolerance_sq: float, max_subdivisions: int = 20) -> types.Polygon:
    r"""
    Adaptively linearize a bezier curve.
    
    :param p0: Start control point (x, y).
    :param p1: First control point (x, y).
    :param p2: Second control point (x, y).
    :param p3: End control point (x, y).
    :param tolerance_sq: Squared tolerance for subdivision.
    :param max_subdivisions: Maximum recursion depth.
    :returns: List of linearized points (x, y).
    :complexity: O(n)
    """

def linearize_bezier_segment(p0: types.Point3D, p1: types.Point3D, p2: types.Point3D, p3: types.Point3D, tolerance: float = 0.1) -> list[types.Point3D]:
    r"""
    Linearize a single bezier segment.
    
    :param p0: Start control point (x, y, z).
    :param p1: First control point (x, y, z).
    :param p2: Second control point (x, y, z).
    :param p3: End control point (x, y, z).
    :param tolerance: Linearization tolerance.
    :returns: List of linearized points (x, y, z).
    :complexity: O(n)
    """

def nearest_tangent_circle_on_bezier(point: types.Point, bezier: types.CubicBezier, radius: float) -> typing.Optional[tuple[types.Point, types.Point, float]]:
    r"""
    Circle through *point* tangent to a cubic Bezier.
    
    :param point: Point the circle must pass through.
    :param bezier: ``(p0, c1, c2, p3)`` control points.
    :param radius: Circle radius.
    :returns: ``(centre, tangent_point, t)`` or None.
    """

def split_bezier(p0: types.Point, p1: types.Point, p2: types.Point, p3: types.Point, t: float) -> tuple[tuple[types.Point, types.Point, types.Point, types.Point], tuple[types.Point, types.Point, types.Point, types.Point]]:
    r"""
    Split a cubic bezier at parameter t.
    
    :param p0: Start control point (x, y).
    :param p1: First control point (x, y).
    :param p2: Second control point (x, y).
    :param p3: End control point (x, y).
    :param t: Split parameter (0..1).
    :returns: Two bezier curves (left, right).
    :complexity: O(1)
    """

