/*----------------------------------------------------------------------------*
 | headerfile Line3D.h                                                        |
 |                                                                            |
 | version 1.00                                                               |
 |                                                                            |
 |                                                                            |
 | This file is part of the 3D Geometry Primer, found at:                     |
 | http://www.flipcode.com/geometry/                                          |        
 |                                                                            |
 | It contains an example implementation of a 3D line.                        |
 | You can find more info in the 3D Geometry Primer on www.flipcode.com.      |
 |                                                                            |
 |                                                                            |
 | Copyright (C) 2002  Bram de Greve                                          |
 |                                                                            |
 | 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 library 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  |
 |                                                                            |
 | You can contact me by e-mail on bdegreve@mail.be                           |
 *----------------------------------------------------------------------------*/

// --- GUARDIAN OF INCLUSION ---------------------------------------------------

#ifndef GUARDIAN_OF_INCLUSION_3DGEOMETRYPRIMER_LINE3D_H
#define GUARDIAN_OF_INCLUSION_3DGEOMETRYPRIMER_LINE3D_H



// --- INCLUDED FILES ----------------------------------------------------------

#include "Vector3D.h"
#include "Point3D.h"



// --- CLASS DEFINITION --------------------------------------------------------

class Line3D
{
public:

    // --- PUBLIC STRUCTORS ---

    // default constructor
    Line3D();

    // constructor taking support point and direction vector (normalize it)
    Line3D(const Point3D& a_support, const Vector3D& a_direction);
        

    // constructor taking support point and a 2nd point of the line
    Line3D(const Point3D& a_support, const Point3D& a_secondPoint);


    // --- PUBLIC ACCESSORS ---

    // return support point
    const Point3D& getSupport() const 
    {
        return m_support;
    }

    // return direction vector
    const Vector3D& getDirection() const 
    {
        return m_direction; 
    }


    // set support point
    void setSupport(const Point3D& a_support)
    {
        m_support = a_support; 
    }

    // set direction vector and normalize it
    void setDirection(const Vector3D& a_direction)
    {
        m_direction = a_direction;
        m_direction.normalize();
    }

    // set line by a support point and direction vector (normalize it)
    void set(const Point3D& a_support, const Vector3D& a_direction);

    // set line by a support point and a second point
    void set(const Point3D& a_support, const Point3D& a_secondPoint);


    // --- PUBLIC METHODS ---

    // return point of line that belongs to parameter value t
    Point3D getPoint(float a_t) const 
    {
        return m_support + a_t * m_direction;
    }

    // return the orthogonal projection of a point onto this line
    Point3D project(const Point3D& a_point);

    // return true if point is point of line
    bool contains(const Point3D& a_point, float a_tolerance = 0.0f);

private:

    // --- PRIVATE MEMBER DATA ---

    // support point
    Point3D m_support;

    // direction vector
    Vector3D m_direction;
};



// --- DISTANCE FUNCTIONS ------------------------------------------------------

// return distance between line and point
float dist(const Line3D& a_line, const Point3D& a_point);

// return distance between point and line
inline float dist(const Point3D& a_point, const Line3D& a_line)
{ 
    return dist(a_line, a_point); 
}


// return distance between two lines
float dist(const Line3D& a_line1, const Line3D& a_line2);



// --- INTERSECTION FUNCTIONS --------------------------------------------------

// intersect two lines and find parameter values for the intersection point
int intersect(const Line3D& a_line1, const Line3D& a_line2, 
              float& a_t1, float& a_t2);



// --- OUTPUT FUNCTIONS --------------------------------------------------------

// write a line to output stream
inline std::ostream& operator<<(std::ostream& a_stream, const Line3D& a_line)
{
    a_stream << "[" << a_line.getSupport();
    a_stream << "-" << a_line.getDirection() << "]";
    return a_stream;
}



// --- GUARDIAN OF INCLUSION ---------------------------------------------------

#endif



// --- END OF FILE Line3D.h ---------------------------------------------------