<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def parallel_lines_parameters(start0, end0, start1, end1):
 r"""Checks if two parallel lines ever meet. Meant as a back-up when :func:`segment_intersection` fails. .. note:: This function assumes but never verifies that the lines are parallel. In the case that the segments are parallel and lie on **different** lines, then there is a **guarantee** of no intersection. However, if they are on the exact same line, they may define a shared segment coincident to both lines. In :func:`segment_intersection`, we utilized the normal form of the lines (via the cross product):
 .. math:: \begin{align*} L_0(s) \times \Delta_0 &\equiv S_0 \times \Delta_0 \\ L_1(t) \times \Delta_1 &\equiv S_1 \times \Delta_1 \end{align*} So, we can detect if :math:`S_1` is on the first line by checking if .. math:: S_0 \times \Delta_0 \stackrel{?}{=} S_1 \times \Delta_0. If it is not on the first line, then we are done, the segments don't meet: .. image:: ../images/parallel_lines_parameters1.png :align: center .. testsetup:: parallel-different1, parallel-different2 import numpy as np from bezier._geometric_intersection import parallel_lines_parameters .. doctest:: parallel-different1 True .. testcleanup:: parallel-different1 import make_images make_images.helper_parallel_lines( start0, end0, start1, end1, "parallel_lines_parameters1.png") If :math:`S_1` **is** on the first line, we want to check that :math:`S_1` and :math:`E_1` define parameters outside of :math:`\left[0, 1\right]`. To compute these parameters: .. math:: L_1(t) = S_0 + s_{\ast} \Delta_0 \Longrightarrow s_{\ast} = \frac{\Delta_0^T \left( L_1(t) - S_0\right)}{\Delta_0^T \Delta_0}. For example, the intervals :math:`\left[0, 1\right]` and :math:`\left[\frac{3}{2}, 2\right]` (via :math:`S_1 = S_0 + \frac{3}{2} \Delta_0` and :math:`E_1 = S_0 + 2 \Delta_0`) correspond to segments that don't meet: .. image:: ../images/parallel_lines_parameters2.png :align: center .. doctest:: parallel-different2 True .. testcleanup:: parallel-different2 import make_images make_images.helper_parallel_lines( start0, end0, start1, end1, "parallel_lines_parameters2.png") but if the intervals overlap, like :math:`\left[0, 1\right]` and :math:`\left[-1, \frac{1}{2}\right]`, the segments meet: .. image:: ../images/parallel_lines_parameters3.png :align: center .. testsetup:: parallel-different3, parallel-different4 import numpy as np from bezier._geometric_intersection import parallel_lines_parameters start0 = np.asfortranarray([1.0, 0.0]) delta0 = np.asfortranarray([2.0, -1.0]) end0 = start0 + 1.0 * delta0 .. doctest:: parallel-different3 False array([[0. , 0.5 ], [0.75, 1. ]]) .. testcleanup:: parallel-different3 import make_images make_images.helper_parallel_lines( start0, end0, start1, end1, "parallel_lines_parameters3.png") Similarly, if the second interval completely contains the first, the segments meet: .. image:: ../images/parallel_lines_parameters4.png :align: center .. doctest:: parallel-different4 False array([[1. , 0. ], [0.4375, 0.5625]]) .. testcleanup:: parallel-different4 import make_images make_images.helper_parallel_lines( start0, end0, start1, end1, "parallel_lines_parameters4.png") .. note:: This function doesn't currently allow wiggle room around the desired value, i.e. the two values must be bitwise identical. However, the most "correct" version of this function likely should allow for some round off. .. 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[bool, Optional[numpy.ndarray]]: A pair of * Flag indicating if the lines are disjoint. * An optional ``2 x 2`` matrix of ``s-t`` parameters only present if the lines aren't disjoint. The first column will contain the parameters at the beginning of the shared segment and the second column will correspond to the end of the shared segment. """

    # NOTE: There is no corresponding "enable", but the disable only applies
    #       in this lexical scope.
    # pylint: disable=too-many-branches
    delta0 = end0 - start0
    line0_const = _helpers.cross_product(start0, delta0)
    start1_against = _helpers.cross_product(start1, delta0)
    if line0_const != start1_against:
        return True, None

    # Each array is a 1D vector, so we can use the vector dot product.
    norm0_sq = np.vdot(delta0, delta0)
    #                S1 = L1(0) = S0 + sA D0
    # <==>        sA D0 = S1 - S0
    #  ==> sA (D0^T D0) = D0^T (S1 - S0)
    s_val0 = np.vdot(start1 - start0, delta0) / norm0_sq
    #                E1 = L1(1) = S0 + sB D0
    # <==>        sB D0 = E1 - S0
    #  ==> sB (D0^T D0) = D0^T (E1 - S0)
    s_val1 = np.vdot(end1 - start0, delta0) / norm0_sq
    # s = s_val0 + t (s_val1 - s_val0)
    # t = 0                                <==> s = s_val0
    # t = 1                                <==> s = s_val1
    # t = -s_val0 / (s_val1 - s_val0)      <==> s = 0
    # t = (1 - s_val0) / (s_val1 - s_val0) <==> s = 1
    if s_val0 <= s_val1:
        # In this branch the segments are moving in the same direction, i.e.
        # (t=0<-->s=s_val0) are both less than (t=1<-->s_val1).
        if 1.0 < s_val0:
            return True, None

        elif s_val0 < 0.0:
            start_s = 0.0
            start_t = -s_val0 / (s_val1 - s_val0)
        else:
            start_s = s_val0
            start_t = 0.0
        if s_val1 < 0.0:
            return True, None

        elif 1.0 < s_val1:
            end_s = 1.0
            end_t = (1.0 - s_val0) / (s_val1 - s_val0)
        else:
            end_s = s_val1
            end_t = 1.0
    else:
        # In this branch the segments are moving in opposite directions, i.e.
        # in (t=0<-->s=s_val0) and (t=1<-->s_val1) we have 0 < 1
        # but ``s_val0 > s_val1``.
        if s_val0 < 0.0:
            return True, None

        elif 1.0 < s_val0:
            start_s = 1.0
            start_t = (s_val0 - 1.0) / (s_val0 - s_val1)
        else:
            start_s = s_val0
            start_t = 0.0
        if 1.0 < s_val1:
            return True, None

        elif s_val1 < 0.0:
            end_s = 0.0
            end_t = s_val0 / (s_val0 - s_val1)
        else:
            end_s = s_val1
            end_t = 1.0
    parameters = np.asfortranarray([[start_s, end_s], [start_t, end_t]])
    return False, parameters