/***************************************************************************
**
**  This file is part of QGpCoreMath.
**
**  This library is free software; you can redistribute it and/or
**  modify it under the terms of the GNU Lesser General Public
**  License as published by the Free Software Foundation; either
**  version 2.1 of the License, or (at your option) any later version.
**
**  This file is distributed in the hope that it will be useful, but WITHOUT
**  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
**  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
**  License for more details.
**
**  You should have received a copy of the GNU Lesser General Public
**  License along with this library; if not, write to the Free Software
**  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
**
**  See http://www.geopsy.org for more information.
**
**  Created: 2003-05-12
**  Copyright: 2003-2019
**    Marc Wathelet
**    Marc Wathelet (ULg, Liège, Belgium)
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include <math.h>

#include "Line2D.h"

namespace QGpCoreMath {

/*!
  Construct a vertical line (parallel to y axis) crossing at (c, 0)
 
  line equation is a * y + b * x=\a c (with a=0 and b=1).
*/
Line2D::Line2D(double c)
{
  TRACE;
  _a=0;
  _b=1;
  _c=c;
}

/*!
  Construct any line except vertical ones.
 
  line equation is a * y + \a b * x=\a c (with a=1)
*/
Line2D::Line2D(double b, double c)
{
  TRACE;
  _a=1;
  _b=b;
  _c=c;
}

/*!
  Construct any line passing by point ( \a x1, \a  y1) and with azimuth \a az (counted clockwize from North).
 
  line equation is a * y + b * x=c
*/
Line2D::Line2D(double x1, double y1, double az)
{
  TRACE;
  if(az==0) {
    _a=0;
    _b=1;
    _c=x1;
  } else {
    _a=1;
    _b=-::tan(0.5 * M_PI - az);
    _c=y1 + _b * x1;
  }
}

/*!
  Copy constructor
*/
Line2D::Line2D(const Line2D &o)
{
  _a=o._a;
  _b=o._b;
  _c=o._c;
}

/*!
  Returns interstection between this line and line \a o. If no intersection is found, \a ok is set to false.
*/
Point2D Line2D::intersect(const Line2D& o, bool& ok) const
{
  TRACE;
  Point2D inter(0, 0);
  if(_a==o._a && _b==o._b) {
    // Either no intersection or std::numeric_limits<double>::infinity() of intersections
    ok=false;
  } else if(_a==0) { // this is vertical
    inter.setX(_c); // _b is 1
    inter.setY(o._c - o._b * inter.x()); // o._a is 1
    ok=true;
  } else if(o._a==0) { // o is vertical
    inter.setX(o._c); // o._b is 1
    inter.setY(_c - _b * inter.x()); // _a is 1
    ok=true;
  } else { // _a and o._a are 1
    inter.setX((_c - o._c)/(_b - o._b));
    inter.setY(_c - _b * inter.x());
    ok=true;
  }
  return inter;
}

} // namespace QGpCoreMath
