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

//------------------------------------------------------------------------------
// lines 
//
// by S. Naeher (1995)
//------------------------------------------------------------------------------


line::line()
{ PTR = new line_rep; }

line::line(const segment& s) 
{ PTR = new line_rep(s); }

line::line(const ray& r) 
{ PTR = new line_rep(r.ptr()->seg); }

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

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

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


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

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


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



bool line::intersection(const segment& s, point& inter) const
{ 
  double orient1 = orientation(ptr()->seg,s.start());
  double orient2 = orientation(ptr()->seg,s.end());

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

segment line::perpendicular(const point& q) const
{ return ptr()->seg.perpendicular(q); }


double line::sqr_dist(const point& q) const
{ segment s = ptr()->seg.perpendicular(q); 
  return s.sqr_length();
}

double line::distance(const point& q) const 
{ return sqrt(sqr_dist(q)); }


line p_bisector(const point& p, const point& q)
{ segment s(center(p,q),q);
  return s.rotate90();
}

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

istream& operator>>(istream& in, line& l)  
{ segment s; 
  in >> s; 
  l = line(s); 
  return in; 
 }

