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

//------------------------------------------------------------------------------
// rat_lines 
//
// S. Naeher (1996)
//------------------------------------------------------------------------------


rat_line::rat_line()
{ PTR = new rat_line_rep; }

rat_line::rat_line(const rat_segment& s) 
{ PTR = new rat_line_rep(s); }

rat_line::rat_line(const rat_point& p, const rat_vector& v) 
{ PTR = new rat_line_rep(rat_segment(p,v)); }

rat_line::rat_line(const rat_ray& r) 
{ PTR = new rat_line_rep(r.ptr()->seg); }

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


line rat_line::to_line() const
{ return line(ptr()->seg.to_segment()); }


bool rat_line::contains(const rat_point& p) const
{ return orientation(ptr()->seg,p) == 0; }

bool rat_line::contains(const rat_segment& s) const
{ return contains(s.start()) && contains(s.end()); }


ostream& operator<<(ostream& out, const rat_line& l) 
{ return out << l.seg(); }

istream& operator>>(istream& in, rat_line& l)  
{ rat_segment s; 
  in >> s; 
  l = rat_line(s); 
  return in; 
 }


bool rat_line::intersection(const rat_line& s, rat_point& inter) const
{ return ptr()->seg.intersection_of_lines(s.ptr()->seg,inter) ; }



bool rat_line::intersection(const rat_segment& s, rat_point& inter) const
{ 
  int orient1 = orientation(ptr()->seg,s.start());
  int orient2 = orientation(ptr()->seg,s.end());

  if (orient1 == 0 && orient2 == 0)
     { inter = s.start(); 
       return true;
     }
  if ( orient1*orient2 <= 0) 
     { ptr()->seg.intersection_of_lines(s,inter);
       return true;
      }
  else
     return false;
}


rat_segment rat_line::perpendicular(const rat_point& q) const
{ return ptr()->seg.perpendicular(q); }


rational rat_line::sqr_dist(const rat_point& q) const
{ rat_segment s = ptr()->seg.perpendicular(q); 
  return s.sqr_length();
}



rat_line p_bisector(const rat_point& p, const rat_point& q)
{ rat_segment s(center(p,q),q);
  return s.rotate90();
}



