<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def segment_intersection(start0, end0, start1, end1):
 r"""Determine the intersection of two line segments. Assumes each line is parametric .. math:: \begin{alignat*}{2} L_0(s) &= S_0 (1 - s) + E_0 s &&= S_0 + s \Delta_0 \\ L_1(t) &= S_1 (1 - t) + E_1 t &&= S_1 + t \Delta_1. \end{alignat*} To solve :math:`S_0 + s \Delta_0 = S_1 + t \Delta_1`, we use the cross product: .. math:: \left(S_0 + s \Delta_0\right) \times \Delta_1 = \left(S_1 + t \Delta_1\right) \times \Delta_1 \Longrightarrow s \left(\Delta_0 \times \Delta_1\right) = \left(S_1 - S_0\right) \times \Delta_1. Similarly .. math:: \Delta_0 \times \left(S_0 + s \Delta_0\right) = \Delta_0 \times \left(S_1 + t \Delta_1\right) \Longrightarrow \left(S_1 - S_0\right) \times \Delta_0 = \Delta_0 \times \left(S_0 - S_1\right) = t \left(\Delta_0 \times \Delta_1\right). .. note:: Since our points are in :math:`\mathbf{R}^2`, the "traditional" cross product in :math:`\mathbf{R}^3` will always point in the :math:`z` direction, so in the above we mean the :math:`z` component of the cross product, rather than the entire vector. For example, the diagonal lines .. math:: \begin{align*} L_0(s) &= \left[\begin{array}{c} 0 \\ 0 \end{array}\right] (1 - s) + \left[\begin{array}{c} 2 \\ 2 \end{array}\right] s \\ L_1(t) &= \left[\begin{array}{c} -1 \\ 2 \end{array}\right] (1 - t) + \left[\begin{array}{c} 1 \\ 0 \end{array}\right] t \end{align*} intersect at :math:`L_0\left(\frac{1}{4}\right) = L_1\left(\frac{3}{4}\right) = \frac{1}{2} \left[\begin{array}{c} 1 \\ 1 \end{array}\right]`. .. image:: ../images/segment_intersection1.png :align: center .. testsetup:: segment-intersection1, segment-intersection2 import numpy as np from bezier._geometric_intersection import segment_intersection .. doctest:: segment-intersection1 :options: +NORMALIZE_WHITESPACE 0.25 0.75 .. testcleanup:: segment-intersection1 import make_images make_images.segment_intersection1(start0, end0, start1, end1, s) Taking the parallel (but different) lines .. math:: \begin{align*} L_0(s) &= \left[\begin{array}{c} 1 \\ 0 \end{array}\right] (1 - s) + \left[\begin{array}{c} 0 \\ 1 \end{array}\right] s \\ L_1(t) &= \left[\begin{array}{c} -1 \\ 3 \end{array}\right] (1 - t) + \left[\begin{array}{c} 3 \\ -1 \end{array}\right] t \end{align*} we should be able to determine that the lines don't intersect, but this function is not meant for that check: .. image:: ../images/segment_intersection2.png :align: center .. doctest:: segment-intersection2 :options: +NORMALIZE_WHITESPACE False .. testcleanup:: segment-intersection2 import make_images make_images.segment_intersection2(start0, end0, start1, end1) Instead, we use :func:`parallel_lines_parameters`: .. testsetup:: segment-intersection2-continued import numpy as np from bezier._geometric_intersection import parallel_lines_parameters start0 = np.asfortranarray([1.0, 0.0]) end0 = np.asfortranarray([0.0, 1.0]) start1 = np.asfortranarray([-1.0, 3.0]) end1 = np.asfortranarray([3.0, -1.0]) .. doctest:: segment-intersection2-continued True .. note:: There is also a Fortran implementation of this function, which will be used if it can be built. Args: start0 (numpy.ndarray):
 A 1D NumPy ``2``-array that is the start vector :math:`S_0` of the parametric line :math:`L_0(s)`. end0 (numpy.ndarray):
 A 1D NumPy ``2``-array that is the end vector :math:`E_0` of the parametric line :math:`L_0(s)`. start1 (numpy.ndarray):
 A 1D NumPy ``2``-array that is the start vector :math:`S_1` of the parametric line :math:`L_1(s)`. end1 (numpy.ndarray):
 A 1D NumPy ``2``-array that is the end vector :math:`E_1` of the parametric line :math:`L_1(s)`. Returns: Tuple[float, float, bool]: Pair of :math:`s_{\ast}` and :math:`t_{\ast}` such that the lines intersect: :math:`L_0\left(s_{\ast}\right) = L_1\left(t_{\ast}\right)` and then a boolean indicating if an intersection was found (i.e. if the lines aren't parallel). """

    delta0 = end0 - start0
    delta1 = end1 - start1
    cross_d0_d1 = _helpers.cross_product(delta0, delta1)
    if cross_d0_d1 == 0.0:
        return None, None, False

    else:
        start_delta = start1 - start0
        s = _helpers.cross_product(start_delta, delta1) / cross_d0_d1
        t = _helpers.cross_product(start_delta, delta0) / cross_d0_d1
        return s, t, True