#ifndef __Vector2_H
#define __Vector2_H

#include <iostream>

using std::ostream; //using namespace std;
using std::endl;

/* 
CLASS 
  Vector2

  Defines a 2D vector class with operators.

KEYWORDS
  linear, algebra, vector, angle, distance, norm, real

AUTHORS
  Zipi Fligelman. (zipo@math.tau.ac.il)

  Copyright: SAMBA group, Tel-Aviv Univ. Israel, 1998.

CHANGES LOG
<UL>
<LI>
</UL>

GOALS
   Though most of the work here is done in 3d, there is sometime need for a 2D
   reference, for example surfaces in a sense are essentially 2D objects.
   Also if one is using an affin transformation from 3D to 2D.
  
  
USAGE
  Many 2D vector operations are supplied including vector addition and 
  subtraction, dot-product mult., multiplication by scalar, distance and 
  angular operators.<P>

  A new Vector2 may be constructed using 2 floats or an array of 2 floats.
  EXAMPLE
    Vector3 unit1(1.0, 0.0);
    float x[2] = {0.0, 1.0};
    Vector3 unit2(x);
  END

  Coordinates may be accessed using the x(int) method which returns the
  vector's given coordinate (1,2) or using the [] operator (0,1).
  EXAMPLE
    if (unit1[0] == 1.0 && unit1[1] == 0.0)  cout << "the E1 vector\n";
    if (unit2[0] != 0.0) cout << "FATAL Error!!!\n";
  END

  Addition, subtraction, multiplication and division by scalar, dot-product
  distance, angle.
  EXAMPLE
    w = u+v;                           // addition
    w-= v;                             // in-place subtraction w==u
    if ((w|u) == 0) cout << "OK\n";    // distance operator |
    if (w^u == 0) cout << "OK\n";      // angle operator ^
    w=2*w;                             // multiplicatio by scalar
    float f=w*v;                       // dot-product;
  END
  Notice: there is no cross product in 2D
*/

class Vector2 
{
  
public: 
  typedef float real; 

  Vector2();
  Vector2(const real& nx, const real& ny);
  Vector2(const real x[2]);
 
  real x() const { return c[0]; }
  real y() const { return c[1]; }

  real operator[](const unsigned short coord) const;

  //// Return Vector2's distance from origin.
  real norm() const;

  //// Return Vector2's squared distance ffrom origin.
  real norm2() const;

  //// Returns Vector2's distance from Vector2 p.
  real dist(const Vector2& p) const;

  //// returns Vector2's squared distance from another Vector2 p.
  real dist2(const Vector2& p) const;

  //// Returns Vector2 addition of two Vector2s.
  friend Vector2 operator+(const Vector2 &, const Vector2 &);

  //// Returns Vector2 subtraction of two Vector2s.
  friend Vector2 operator-(const Vector2 &, const Vector2 &);

  //// Returns Vector2 negative.
  friend Vector2 operator-(const Vector2 &);

  //// Returns dot product of two Vector2s.
  friend real operator*(const Vector2 &, const Vector2 &);

  //// Returns vector multiplied by scalar m.
  friend Vector2 operator*(const Vector2 &, const real &);

  //// Returns vector multiplied by scalar m.
  friend Vector2 operator*(const real &, const Vector2 &);

  //// Returns vector divided by scalar m.
  friend Vector2 operator/(const Vector2 &, const real &);

  //// Returns distance between 2 Vector2s (similar to dist).
  friend real operator|(const Vector2 &, const Vector2 &);

  //// Returns angle between p1 and p2 in radians.
  friend real operator^(const Vector2 &, const Vector2 &);

  //// Vector2 addition of another Vector2's coordinates.
  Vector2& operator+=(const Vector2 &);

  //// Vector2 subtraction of another Vector2's coordinates.
  Vector2& operator-=(const Vector2 &);

  //// Multiplies coordinates by scalar m.
  Vector2& operator*=(const real& m);

  //// Divides coordinates by scalar m.
  Vector2& operator/=(const real &m);

  //// Outputs coordinates delimited by single space.
  friend ostream& operator<<(ostream& s, const Vector2& v);
  
private:
  //// the coordinates
  real c[2]; 
  
};
  



#endif


