// $Source: /usr/local/SimSoft/SoftShop/XMath/Vec3D/Vec3D.h,v $
// $Revision: 1.20 $
// $Author: baum $
// $Date: 2001/11/29 15:52:25 $
//
// Login name of the user who locked the revision
// $Locker:  $
// Tag name used to checkout the file
// $Name: Release-20 $
// State assigned to revision
// $State: Exp $
//
//
// $Log: Vec3D.h,v $
// Revision 1.20  2001/11/29 15:52:25  baum
// -In Kalender.cpp und Kalender.h Handsteuerung eingebaut
//

#ifndef _VEC3D_H
#define _VEC3D_H	1

#include <iostream.h>
#include "Angle.h"

#ifdef _VEC3D_CPP
#  undef _impexp
#  define _impexp __declspec(dllexport)
#elif defined BUILD_XMATH_DLL
#  undef _impexp
#  define _impexp
#else
#  undef _impexp
#  define _impexp __declspec(dllimport)
#endif

#if defined __GNUC__ || defined __hpux
#  undef _impexp
#  define _impexp
#endif

#ifndef _HMATRX3D_H
class HMatrx3D;
#endif

// Please note, that following common mathematical conventions
// the XMath-subsystem defines Vectors to be column vectors.
// All Vector- and Matrix-operations are implemented suitably.

//==================================================================
//		Klassen-Header
//		fuer class Vec3D
//==================================================================

class _impexp Vec3D {
  public:
    //Konstruktoren
    Vec3D ();
    Vec3D (const Vec3D&);
    Vec3D (double x, double y, double z);

    //Destructor
    ~Vec3D ();

    //Zuweisungsoperator
    Vec3D& operator = (const Vec3D&);

    //Vergleichsoperatoren
    bool operator == (const Vec3D&) const;
    bool operator != (const Vec3D&) const;

    // NOT und VOID*-Operatoren
    bool operator ! () const;
    operator void* () const;

    //arithmetische Operatoren
    Vec3D  operator - () const;

    Vec3D  operator + (const Vec3D&) const;
    Vec3D& operator += (const Vec3D&);

    Vec3D  operator - (const Vec3D&) const;
    Vec3D& operator -= (const Vec3D&);

    Vec3D  operator * (const double&) const;
    Vec3D& operator *= (const double&);

    // though mathematically not correct, these 2 are provided for easier use
    Vec3D  operator *  (const HMatrx3D&) const;
    Vec3D& operator *= (const HMatrx3D&);

    // Scale Vec with an other Vec
    Vec3D& scale (const Vec3D&);

    //Punkt- oder Skalarprodukt
    double dot (const Vec3D&) const;

    //Kreuzprodukt (default result Vec3D (0,0,0))
    Vec3D cross (const Vec3D&) const;

    //IO-Funktionen
    istream& read (istream&);
    ostream& print (ostream&) const;
    void stream (ostream&, unsigned spaces = 0) const;

    //Values
    double X () const;
    double Y () const;
    double Z () const;

    // get Double-Array for OpenGL (double[3])
    const double* OpenGLForm () const;

    // Betrag
    double len () const;

    //Einheitsvector
    Vec3D unit () const;

    // projection on v
    Vec3D projOn (const Vec3D& v) const;

    // is collinear to v
    bool isCollinear (const Vec3D& v) const;

    // has same direction as v
    bool hasSameDir (const Vec3D& v) const;

    // angle between vecs
    Angle angle (const Vec3D&) const;

  private:
    //data members
    double ObjVal[3];

  //friends

}; // class Vec3D (header)


// Einheitsvektoren in Richtung der Grundachsen
extern const Vec3D _impexp EX;
extern const Vec3D _impexp EY;
extern const Vec3D _impexp EZ;
extern const Vec3D _impexp ESCALE;

inline istream& operator >> (istream& i, Vec3D& v) {
  return v.read (i);
}

inline ostream& operator << (ostream& o, const Vec3D& v) {
  return v.print (o);
}

#endif
