// $Source: /local/data/cvs/yellowbank/tile/qpoint.cc,v $
// $Revision: 1.2 $
// $State: Exp $
// $Date: 2004/07/19 03:54:07 $
// $Author: yrp001 $
// $Locker:  $

#include "qpoint.h"

qpoint::
qpoint()
  : _x( 0 ),
    _y( 0 ),
    _sortoption( sortxy )
{}

qpoint::
qpoint( const qpoint& pt )
  : _x( pt._x ),
    _y( pt._y ),
    _sortoption( pt._sortoption )
{}

qpoint::
qpoint( double xo, double yo )
  : _x( xo ),
    _y( yo ),
    _sortoption( sortxy )
{}

qpoint::
qpoint( const qpoint& point, double angle, double length )
  : _sortoption( sortxy )
{
  qangle a( angle );
  _x = a.cosine() * length;
  _y = a.sine() * length;
  _x += point.getx();
  _y += point.gety();
}

void
qpoint::
set( double x, double y ) {
  _x = x;
  _y = y;
}

void
qpoint::
setx( double x ) {
    _x = x;
}
  
void
qpoint::
sety( double y ) {
    _y = y;
}
  
double
qpoint::
length() const {
  return _length( _x, _y );
}

qangle
qpoint::
angle() const {
  return qangle( _x, _y, 0 );
}

float
qpoint::
anglef() const {
  qangle a( _x, _y, 0 );
  return a.valrad();
}

void
qpoint::
rotate90cw() {
  double t = _y;
  _y = -_x;
  _x = t;
}

void
qpoint::
rotate90cw( const qpoint& center ) {
  _x -= center._x;
  _y -= center._y;
  rotate90cw();
  _x += center._x;
  _y += center._y;
}

void
qpoint::
rotate90ccw() {
  double t = _x;
  _x = -_y;
  _y = t;
}

void
qpoint::
rotate90ccw( const qpoint& center ) {
  _x -= center._x;
  _y -= center._y;
  rotate90ccw();
  _x += center._x;
  _y += center._y;
}

void
qpoint::
rotate180() {
  double t = _x;
  _x = _y;
  _y = t;
}

qpoint
midpoint( const qpoint& p1, const qpoint& p2 ) {
  double xn, yn;
  xn = ( p1._x + p2._x ) / 2.0;
  yn = ( p1._y + p2._y ) / 2.0;
  return qpoint( xn, yn );
}

qpoint
operator-( const qpoint& p1, const qpoint& p2 ) {
  return qpoint( p1._x - p2._x, p1._y - p2._y );
}

qpoint
operator+( const qpoint& p1, const qpoint& p2 ) {
  return qpoint( p1._x + p2._x, p1._y + p2._y );
}

qpoint&
qpoint::
operator=( const qpoint& other) {
  if( &other == this )
    return *this;
  _x = other._x;
  _y = other._y;
  return *this;
}

int
qpoint::
operator==( const qpoint& p2 ) {
  return( _x == p2._x && _y == p2._y );
}

int
qpoint::
operator!=( const qpoint& p2 ) {
  return( _x != p2._x || _y != p2._y );
}

void
qpoint::
setcomp( qpoint::sorttype option ) {
  _sortoption = option;
}

int
qpoint::
operator<( const qpoint& p2 ) {
  if( _sortoption == sortxy )
    return sortcompxy( p2 );
  return sortcompyx( p2 );
}

int
qpoint::
sortcompxy( const qpoint& p2 ) {
  if( _x < p2._x )
    return -1;
  else if( _x > p2._x )
    return 1;
  else if( _y < p2._y )
    return -1;
  else if( _y > p2._y )
    return 1;
  return 0;
}

int
qpoint::
sortcompyx( const qpoint& p2 ) {
  if( _y < p2._y )
    return -1;
  else if( _y > p2._y )
    return 1;
  else if( _x < p2._x )
    return -1;
  else if( _x > p2._x )
    return 1;
  return 0;
}

double
qpoint::
clip( double val, double min, double max ) {
  if( min > max ) {
    std::cerr << "Class qpoint: invalid arguments to clip()" << std::endl;
    return 1;
  }
  if( val < min )
    return min;
  else if( val > max )
    return max;
  return val;
}

double
qpoint::
wrapval( double val, double limit ) const {
  double rem;
  rem = fmod( val, limit );
  if( rem < 0.0 )
    return( limit + rem );
  return( rem );
}

double
qpoint::
ricochet( double val, double offset ) const {
  double newval = val + offset;
  if( newval < 0.0 ) {
    newval *= -1;
    if( newval > 1.0 )
      ricochet( 0.0, newval );
    return( newval );
  } else if( newval > 1.0 ) {
    newval = 2.0 - newval;
    if( newval < 0.0 )
     ricochet( 1.0, newval - 1.0 );
    return( newval );
  }
  return( newval );
}

double
qpoint::
_length( double x, double y ) const {
  return sqrt( pow( x, 2.0 ) + pow( y, 2.0 ) );
}

std::ostream&
operator<<( std::ostream& os, qpoint& pt ) {
  return os << pt._x << " " << pt._y;
}

std::istream&
operator>>( std::istream& is, qpoint& pt ) {
  double xt, yt;
  is >> xt;
  is >> yt;

  pt.setx( xt );
  pt.sety( yt );

  return is;
}






