/*******************************************************************************
+
+  LEDA 3.5
+
+  _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/ray.h>
#include <math.h>

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


ray::ray()
{ PTR = new ray_rep; }

ray::ray(const segment& s) 
{ PTR = new ray_rep(s); }

ray::ray(const point& x, const point& y)    
{ PTR = new ray_rep(segment(x,y)); }

ray::ray(const point& p, const vector& v) 
{ PTR = new ray_rep(segment(p,v)); }

ray::ray(const point& p, double alpha) 
{ PTR = new ray_rep(segment(p,alpha,1)); }
  


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


bool ray::contains(const segment& s) const
{ return contains(s.start()) && contains(s.end()); }


bool ray::intersection(const ray& r, point& inter) const
{ if (ptr()->seg.intersection_of_lines(r.ptr()->seg,inter))
     return contains(inter) && r.contains(inter);
  else
     return false;
}


bool ray::intersection(const segment& s, point& inter) const
{ if (ptr()->seg.intersection_of_lines(s,inter))
     return contains(inter) && s.contains(inter);
  else
     return false;
}


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


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

istream& operator>>(istream& in, ray& r)  
{ segment s; 
  in >> s; 
  r = ray(s); 
  return in; 
 }

