/*******************************************************************************
+
+  LEDA 3.5
+
+  _rat_ray.c
+
+  This file is part of the LEDA research version (LEDA-R) that can be 
+  used free of charge in academic research and teaching. Any commercial
+  use of this software requires a license which is distributed by the
+  LEDA Software GmbH, Postfach 151101, 66041 Saarbruecken, FRG
+  (fax +49 681 31104).
+
+  Copyright (c) 1991-1997  by  Max-Planck-Institut fuer Informatik
+  Im Stadtwald, 66123 Saarbruecken, Germany     
+  All rights reserved.
+ 
*******************************************************************************/


#include <LEDA/rat_ray.h>
#include <math.h>

//------------------------------------------------------------------------------
// rat_rays 
//
// by S. Naeher (1995,1996)
//------------------------------------------------------------------------------


rat_ray::rat_ray()
{ PTR = new rat_ray_rep; }

rat_ray::rat_ray(const rat_segment& s) 
{ if (s.is_trivial())
     error_handler(1,"rat_ray::rat_ray: cannot construct ray from trivial segment");
  PTR = new rat_ray_rep(s); 
}

rat_ray::rat_ray(const rat_point& x, const rat_point& y)    
{ PTR = new rat_ray_rep(rat_segment(x,y)); }


ray rat_ray::to_ray() const
{ return ray(ptr()->seg.to_segment()); }


bool rat_ray::contains(const rat_point& p) const
{ if (orientation(ptr()->seg,p) == 0) 
  { // p lies on line
    rat_segment s = ptr()->seg.rotate90();
    return (orientation(s,p) <= 0);
   }
  return false;
}


bool rat_ray::contains(const rat_segment& s) const
{ return contains(s.source()) && contains(s.target()); }


bool rat_ray::intersection(const rat_ray& r, rat_point& inter) const
{ if ( cmp_slopes(*this,r) == 0 )
     { if ( contains(r.source()) )
          { inter = r.source(); return true; }
       if ( r.contains(source()) )
          { inter = source(); return true; }
       return false;
     }

  if ( ptr()->seg.intersection_of_lines(r.ptr()->seg,inter) )
     return contains(inter) && r.contains(inter);
  else
     return false;
}


bool rat_ray::intersection(const rat_segment& s, rat_point& inter) const
{ if ( s.is_trivial() )
  { if ( contains(s.source()) ) 
       { inter = s.source(); return true; }
    else
    return false;
  }
  if ( cmp_slopes(*this,rat_ray(s)) == 0 )
     { if ( contains(s.source()) )
          { inter = s.source(); return true; }
       if ( contains(s.target()) )
          { inter = s.target(); return true; }
       return false;
     }

    if (ptr()->seg.intersection_of_lines(s,inter))
     return contains(inter) && s.contains(inter);
  else
     return false;
}


bool rat_ray::operator==(const rat_ray& g) const 
{ rat_segment s1 = ptr()->seg;
  rat_segment s2 = g.ptr()->seg;
  return (s1.source() == s2.source()) && contains(s2); 
}


ostream& operator<<(ostream& out, const rat_ray& r) 
{ return out << r.seg(); }

istream& operator>>(istream& in, rat_ray& r)  
{ rat_segment s; 
  in >> s; 
  r = rat_ray(s); 
  return in; 
 }



