def line_line_intersect(x1, y1, x2, y2, x3, y3, x4, y4, line_segment = False, half_segment = False):
   """Returns the intersection x',y' of two lines x,y 1 to 2 and x,y 3 to 4.

   arguments:
      x1, y1, x2, y2: coordinates of two points defining first line
      x3, y3, x4, y4: coordinates of two points defining second line
      line_segment (bool, default False): if False, both lines are treated as unbounded; if True second line
         is treated as segment bounded by both end points and first line bounding depends on half_segment arg
      half_segment (bool, default False): if True and line_segment is True, first line is bounded only at
         end point x1, y1, whilst second line is fully bounded; if False and line_segment is True, first line
         is also treated as fully bounded; ignored if line_segment is False (ie. both lines unbounded)

   returns:
      pair of floats being x, y of intersection point; or None, None if no qualifying intersection

   note:
      in the case of bounded line segments, both end points are 'included' in the segment
   """

   divisor = (x1 - x2) * (y3 - y4)  -  (y1 - y2) * (x3 - x4)
   if divisor == 0.0: return None, None  # parallel or coincident lines

   if line_segment:
      t = ((x1 - x3) * (y3 - y4)  -  (y1 - y3) * (x3 - x4))  /  divisor
      if t < 0.0 or (not half_segment and t > 1.0): return None, None
      u = -((x1 - x2) * (y1 - y3)  -  (y1 - y2) * (x1 - x3))  /  divisor
      if not (0.0 <= u <= 1.0): return None, None
      x = x1  +  t * (x2 - x1)
      y = y1  +  t * (y2 - y1)

   else:
      a = x1 * y2  -  y1 * x2
      b = x3 * y4  -  y3 * x4
      x = (a * (x3 - x4)  -  (x1 - x2) * b)  /  divisor
      y = (a * (y3 - y4)  -  (y1 - y2) * b)  /  divisor

   return x, y