#ifndef PLANE_H
#define PLANE_H

#include <print.h>
#include <point.h>
#include <typedefs.h>
#include <zero.h>

/*!
\brief Mathematical plane equation.

  N*X = d.  N is the normal and d is the plane equations 
  constant.
*/
class plane
{
public:

  /** nml*X=d0. */
  point3<double> nml;
  /** The plane constant. */
  double d0;

  /** Is the normals x component zero? */
  boolc nmlxIsZero() const
    { return nml.x*nml.x<zero<double>::val; }
  /** Is the normals y component zero? */
  boolc nmlyIsZero() const
    { return nml.y*nml.y<zero<double>::val; }
  /** Is the normals z component zero? */
  boolc nmlzIsZero() const
    { return nml.z*nml.z<zero<double>::val; }

  /** Construct a plane. */
  plane( point3<double> const & nml_, doublec d0_ )
    : nml(nml_), d0(d0_) {}

  /** Construct a plane through three points. */
  plane
  (
    bool & valid,
    point3<double> const & p0,
    point3<double> const & p1,
    point3<double> const & p2
  );

  /** Find the line A+Bt that is the two planes 
      intersection. */
  boolc intersects
  ( 
    point3<double> & A,
    point3<double> & B,
    plane const & P2 
  ) const;

  /** Determine if a point is on a plane or not. */
  boolc isPointOnPlane( point3<double> const & p ) const
    { return zero<double>::test(nml.dot(p)-d0); }

  /** Write this object as a string. 
      The normal first then the plane constant. */
  operator stringc () const;

};

#endif


