Name
    Math::Intersection::Circle::Line - Find the points at which circles and lines
    intersect.

Synopsis
    use Math::Intersection::Circle::Line q(:all);
    use Test::More q(no_plan);
    use utf8;

    # A line segment across a circle is never longer than the diameter

    if (1)                                                                         # Random circle and random line
     {my ($x, $y, $r, $𝘅, $𝘆, $𝕩, $𝕪) = map {rand()} 1..7;
      intersectionCircleLine                                                       # Find intersection of a circle and a line
       {return ok 1 unless @_ == 4;                                                # Ignore line unless it crosses circle
        ok &vectorLength(@_) <= 2*$r;                                              # Length if line segment is less than or equal to that of a diameter
            } $x, $y, $r, $𝘅, $𝘆, $𝕩, $𝕪;                                                # Circle and line to be intersected
     }

    # The length of a side of a hexagon is the radius of a circle inscribed through
    # its vertices

    if (1)
     {my ($x, $y, $r) = map {rand()} 1..3;                                         # Random circle
      my @p = intersectionCircles {@_} $x, $y, $r, $x+$r, $y, $r;                  # First step of one radius
            my @𝗽 = intersectionCircles {@_} $x, $y, $r, $p[0], $p[1], $r;               # Second step of one radius
            my @q = !&near($x+$r, $y, @𝗽[0,1]) ? @𝗽[0,1] : @𝗽[2,3];                      # away from start point
            my @𝗾 = intersectionCircles {@_} $x, $y, $r, $q[0], $q[1], $r;               # Third step of one radius
      ok &near2(@𝗾[0,1], $x-$r, $y) or                                             # Brings us to a point
         &near2(@𝗾[2,3], $x-$r, $y);                                               # opposite to the start point
     }

    # Circle through three points chosen at random has the same centre regardless of
    # the pairing of the points

    sub circleThrough3
     {my ($x, $y, $𝘅, $𝘆, $𝕩, $𝕪) = @_;                                            # Three points
           &intersectionLines
            (sub                                                                         # Intersection of bisectors is the centre of the circle
              {my @r =(&vectorLength(@_, $x, $y),                                        # Radii from centre of circle to each point
                       &vectorLength(@_, $𝘅, $𝘆),
                       &vectorLength(@_, $𝕩, $𝕪));
               ok &near(@r[0,1]);                                                        # Check radii are equal
               ok &near(@r[1,2]);
          @_                                                                       # Return centre
                    }, rotate90AroundMidPoint($x, $y, $𝘅, $𝘆),                                 # Bisectors between pairs of points
                       rotate90AroundMidPoint($𝕩, $𝕪, $𝘅, $𝘆));
     }

    if (1)
     {my (@points) = map {rand()} 1..6;                                            # Three points chosen at random
      ok &near2(circleThrough3(@points), circleThrough3(@points[2..5, 0..1]));     # Circle has same centre regardless
      ok &near2(circleThrough3(@points), circleThrough3(@points[4..5, 0..3]));     # of the pairing of the points
     }

Description
    Find the points at which circles and lines intersect.

    Fast and easy to use these functions are written in 100% Pure Perl.

 intersectionCircles 𝘀𝘂𝗯 circle1, circle2
    Find the points at which two circles intersect.  Complains if the two circles
    are identical.

    𝘀𝘂𝗯 specifies a subroutine to be called with the coordinates of the
    intersection points if there are any or an empty parameter list if there are
    no points of intersection.

    A circle is specified by supplying a list of three numbers:

     (𝘅, 𝘆, 𝗿)

    where (𝘅, 𝘆) are the coordinates of the centre of the circle and (𝗿) is its
    radius.

    Returns what ever is returned by 𝘀𝘂𝗯.

 intersectionCircleLine 𝘀𝘂𝗯 circle, line
    Find the points at which a circle and a line intersect.

     𝘀𝘂𝗯 specifies a subroutine to be called with the coordinates of the
    intersection points if there are any or an empty parameter list if there are
    no points of intersection.

    A circle is specified by supplying a list of three numbers:

     (𝘅, 𝘆, 𝗿)

    where (𝘅, 𝘆) are the coordinates of the centre of the circle and (𝗿) is its
    radius.

    A line is specified by supplying a list of four numbers:

     (x, y, 𝘅, 𝘆)

    where (x, y) and (𝘅, 𝘆) are the coordinates of two points on the line.

    Returns what ever is returned by 𝘀𝘂𝗯.

 intersectionLines 𝘀𝘂𝗯 line1, line2
    Finds the point at which two lines intersect.

     𝘀𝘂𝗯 specifies a subroutine to be called with the coordinates of the
    intersection point or an empty parameter list if the two lines do not
    intersect.

    Complains if the two lines are collinear.

    A line is specified by supplying a list of four numbers:

     (x, y, 𝘅, 𝘆)

    where (x, y) and (𝘅, 𝘆) are the coordinates of two points on the line.

    Returns what ever is returned by 𝘀𝘂𝗯.

 intersectionLinePoint 𝘀𝘂𝗯 line, point
    Find the point on a line closest to a specified point.

     𝘀𝘂𝗯 specifies a subroutine to be called with the coordinates of the
    intersection points if there are any.

    A line is specified by supplying a list of four numbers:

     (x, y, 𝘅, 𝘆)

    where (x, y) and (𝘅, 𝘆) are the coordinates of two points on the line.

    A point is specified by supplying a list of two numbers:

     (𝘅, 𝘆)

    where (𝘅, 𝘆) are the coordinates of the point.

    Returns what ever is returned by 𝘀𝘂𝗯.

 $Math::Intersection::Circle::Line::near
    As a finite computer cannot represent an infinite plane of points it is
    necessary to make the plane discrete by merging points closer than the
    distance contained in this variable, which is set by default to 1e-6.

Export
    The following functions are exported by default:

   "intersectionCircles()"
   "intersectionCircleLine()"
   "intersectionLines()"
   "intersectionLinePoint()"

    Optionally some useful helper functions can also be exported either by
    specifying the tag :all or by naming the required functions individually:

   "midPoint()"
   "near()"
   "near2()"
   "near4()"
   "rotate90CW()"
   "rotate90CCW ()"
   "rotate90AroundMidPoint()"
   "vectorLength()"

Installation
    Standard Module::Build process for building and installing modules:

      perl Build.PL
      ./Build
      ./Build test
      ./Build install

    Or, if you're on a platform (like DOS or Windows) that doesn't require
    the "./" notation, you can do this:

      perl Build.PL
      Build
      Build test
      Build install

Author
    Philip R Brenan at gmail dot com

    http://www.appaapps.com

Copyright
    Copyright (c) 2015 Philip R Brenan.

    This module is free software. It may be used, redistributed and/or
    modified under the same terms as Perl itself.