// $Source: /usr/local/SimSoft/SoftShop/XMath/Vec2D/Vec2D.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: Vec2D.h,v $
// Revision 1.20  2001/11/29 15:52:25  baum
// -In Kalender.cpp und Kalender.h Handsteuerung eingebaut
//

#ifndef _VEC2D_H
#define _VEC2D_H	1


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

#ifdef _VEC2D_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 _HMATRX2D_H
class HMatrx2D;
#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 Vec2D
//==================================================================

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

    //Destructor
    ~Vec2D ();

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

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

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

    //arithmetische Operatoren
    Vec2D  operator -  () const;

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

    Vec2D  operator -  (const Vec2D&) const;
    Vec2D& operator -= (const Vec2D&);
	
    Vec2D  operator *  (const double&) const;
    Vec2D& operator *= (const double&);

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

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

    //Punkt- oder Skalarprodukt	
    double dot (const Vec2D&) const;
		
    //Kreuzprodukt (default result Vec2D (0,0))
    Vec2D cross (const Vec2D&) const;

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

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

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

    // Betrag
    double len () const;

    //Einheitsvector
    Vec2D unit () const;

    // pojection on v
    Vec2D projOn (const Vec2D& v) const;

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

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

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

  private:
    double ObjVal[2];

  //friends

}; // class Vec2D (header)


// Einheitsvektoren in Richtung der Grundachsen
extern const Vec2D _impexp E2X;
extern const Vec2D _impexp E2Y;


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

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

#endif
