/*
* $Id: linecros.c,v 1.3 2003/09/11 16:12:48 markus Exp $
*
****************************************************************************
*
* MODULE:       Vector library 
*   	    	
* AUTHOR(S):    Original author CERL, probably Dave Gerdes.
*               Update to GRASS 5.7 Radim Blazek.
*
* PURPOSE:      Lower level functions for reading/writing/manipulating vectors.
*
* COPYRIGHT:    (C) 2001 by the GRASS Development Team
*
*               This program is free software under the GNU General Public
*   	    	License (>=v2). Read the file COPYING that comes with GRASS
*   	    	for details.
*
*****************************************************************************/
#include <stdio.h>
/***************************************************************
* test_for_intersection (ax1,ay1,ax2,ay2,bx1,by1,bx2,by2)
*   double ax1,ax2,ay1,ay2;
*   double bx1,bx2,by1,by2;
*
* returns
*   0 no intersection at all
*   1 the line segments intersect at only one point
*  -1 the line segments intersect at many points, i.e., overlapping
*     segments from the same line
*
* find_intersection (ax1,ay1,ax2,ay2,bx1,by1,bx2,by2,x,y)
*   double ax1,ax2,ay1,ay2;
*   double bx1,bx2,by1,by2;
*   double *x,*y;
*
* returns
*   0 no intersection
*   1 x,y set to (unique) intersection
*  -1 lines overlap, no unique intersection
*
* Based on the following:
*
*    (ax2-ax1)r1 - (bx2-bx1)r2 = ax2 - ax1
*    (ay2-ay1)r1 - (by2-by1)r2 = ay2 - ay1
*
* Solving for r1 and r2, if r1 and r2 are between 0 and 1,
* then line segments (ax1,ay1)(ax2,ay2) and (bx1,by1)(bx2,by2)
* intersect
****************************************************************/

#define D  ((ax2-ax1)*(by1-by2) - (ay2-ay1)*(bx1-bx2))

#define D1 ((bx1-ax1)*(by1-by2) - (by1-ay1)*(bx1-bx2))

#define D2 ((ax2-ax1)*(by1-ay1) - (ay2-ay1)*(bx1-ax1))

int 
dig_test_for_intersection (
			    double ax1, double ay1,
			    double ax2, double ay2,
			    double bx1, double by1,
			    double bx2, double by2)
{
  register double d, d1, d2;
  double t;

  d = D;
  d1 = D1;
  d2 = D2;

  if (d > 0)
    return (d1 >= 0 && d2 >= 0 && d >= d1 && d >= d2);
  if (d < 0)
    return (d1 <= 0 && d2 <= 0 && d <= d1 && d <= d2);

/* lines are parallel */
  if (d1 || d2)
    return 0;

/* segments are colinear. check for overlap */
  if (ax1 > ax2)
    {
      t = ax1;
      ax1 = ax2;
      ax2 = t;
    }
  if (bx1 > bx2)
    {
      t = bx1;
      bx1 = bx2;
      bx2 = t;
    }
  if (ax1 > bx2)
    return 0;
  if (ax2 < bx1)
    return 0;

/* there is overlap */

  if (ax1 == bx2 || ax2 == bx1)
    return 1;			/* endpoints only */
  return -1;			/* true overlap   */
}


int 
dig_find_intersection (
			double ax1, double ay1,
			double ax2, double ay2,
			double bx1, double by1,
			double bx2, double by2,
			double *x, double *y)
{
  register double d, r1, r2;
  double t;

  d = D;

  if (d)
    {

      r1 = D1 / d;
      r2 = D2 / d;
      if (r1 < 0 || r1 > 1 || r2 < 0 || r2 > 1)
	{
	  return 0;
	}
      *x = ax1 + r1 * (ax2 - ax1);
      *y = ay1 + r1 * (ay2 - ay1);
      return 1;
    }

/* lines are parallel */
  if (D1 || D2)
    {
      return 0;
    }

/* segments are colinear. check for overlap */
  if (ax1 > ax2)
    {
      t = ax1;
      ax1 = ax2;
      ax2 = t;
    }
  if (bx1 > bx2)
    {
      t = bx1;
      bx1 = bx2;
      bx2 = t;
    }
  if (ax1 > bx2)
    return 0;
  if (ax2 < bx1)
    return 0;

/* there is overlap */

  if (ax1 == bx2)
    {
      *x = ax1;
      *y = ay1;
      return 1;			/* endpoints only */
    }
  if (ax2 == bx1)
    {
      *x = ax2;
      *y = ay2;
      return 1;			/* endpoints only */
    }
  return -1;			/* overlap, no single intersection point */
}
