khanat-opennel-code/code/ryzom/server/src/ai_share/ai_vector.h
acemtp@users.sourceforge.net d5c601ffa5 initial version
2010-05-06 02:08:41 +02:00

148 lines
5.6 KiB
C++

// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef RYAI_VECTOR_H
#define RYAI_VECTOR_H
#include "nel/misc/types_nl.h"
#include "nel/misc/vector_2d.h"
#include "angle.h"
#include "ai_coord.h"
class CAIVectorMirror;
// ***************************************************************************
/** A 2D vector of CAICoord.
This class is a simple 2D vector based on CAICoord components. It can be used
in most computations involving entity positions that do not need height
information.
CAIVectorMirror is an extension of this class which is linked to a mirror
field to automatically update an entity position.
*/
class CAIVector
{
public: // Methods.
/// Constructors
template <class V> CAIVector(const V &v) : _x(v.x()), _y(v.y()) {}
inline explicit CAIVector(const CAIVectorMirror &vectorMirror);
CAIVector() {}
explicit CAIVector(const NLMISC::CVector2d &v) : _x(v.x), _y(v.y) {}
explicit CAIVector(const CAICoord& x, const CAICoord& y) : _x(x), _y(y) {}
explicit CAIVector(double x, double y) : _x(x), _y(y)
{}
// assignment operators
CAIVector& operator=(const NLMISC::CVector2d &v) { _x=v.x; _y=v.y; return *this; }
// basic accessors x(), y(), setX(), setY(), setXY
const CAICoord &x() const { return _x; }
const CAICoord &y() const { return _y; }
template <class C> void setX(const C &x) { _x=x; }
template <class C> void setY(const C &y) { _y=y; }
template <class C> void setXY(const C &x, const C &y) { _x=x; _y=y; }
template <class C> void setXY(const C &xy) { *this=xy; }
// Base Maths: +=, +, -=, - vs CVector2d, CAIVector, CAIVectorMirror
template <class V> CAIVector &operator+=(const V &v) { _x+=v.x(); _y+=v.y(); return *this; }
template <class V> CAIVector &operator-=(const V &v) { _x-=v.x(); _y-=v.y(); return *this; }
template <class V> CAIVector operator+(const V &v) const { CAIVector rv(*this); return (rv+=v); }
template <class V> CAIVector operator-(const V &v) const { CAIVector rv(*this); return (rv-=v); }
CAIVector &operator+=(const NLMISC::CVector2d &v) { _x+=v.x; _y+=v.y; return *this; }
CAIVector &operator-=(const NLMISC::CVector2d &v) { _x-=v.x; _y-=v.y; return *this; }
// Base Maths: *=, *, /=, / vs double, int, etc
template <class C> CAIVector &operator*=(C c) { _x*=c; _y*=c; return *this; }
template <class C> CAIVector &operator/=(C c) { _x/=c; _y/=c; return *this; }
// template <class C> CAIVector operator*(C c) const { return CAIVector(_x*c, _y*c); }
CAIVector operator*(double c) const { return CAIVector(_x*c, _y*c); }
template <class C> CAIVector operator/(C c) const { return CAIVector(_x/c, _y/c); }
// Base Maths: unary -
CAIVector operator-() const { return CAIVector(-_x, -_y); }
// Advanced Maths.
// Dot product.
template <class V> double dot(const V &v) const { return _x.asDouble()*v.x().asDouble() +
_y.asDouble()*v.y().asDouble(); }
template <class V> double vectorDot(const V &v) const { return _x.asDouble()*v.y().asDouble() -
_y.asDouble()*v.x().asDouble(); }
// Return the norm of the vector.
double norm() const { return sqrt(sqrnorm()); }
// Return the square of the norm of the vector.
double sqrnorm() const { return _x.asDouble()*_x.asDouble() +
_y.asDouble()*_y.asDouble(); }
double quickNorm() const { double dx=fabs(x().asDouble()),
dy=fabs(y().asDouble());
return (dx>dy)? (dx+dy/2): (dy+dx/2); }
// Normalize the vector.
CAIVector &normalize(float newNorm=1.f)
{
double d= norm();
if(d>0.0)
operator*=((newNorm/1000)/d);
return *this;
}
/// Return the vector normalized.
/* CAIVector normed() const
{
CAIVector v= *this;
v.normalize();
return v;
}
*/
// return the orientation of the vector as a CAngle
CAngle asAngle() const
{
return CAngle(atan2(_y.asDouble(),_x.asDouble()));
}
template <class V> bool operator==(const V &v) const { return _x==v.x() && _y==v.y(); }
template <class V> bool operator!=(const V &v) const { return _x!=v.x() || _y!=v.y(); }
bool isNull() const { return _x.asInt()==0 && _y.asInt()==0; }
template <class V> CAngle angleTo(const V &v) const { return CAngle(atan2((v.y()-y()).asDouble(),
(v.x()-x()).asDouble())); }
template <class V> double distTo(const V &v) const { return (*this-v).norm(); }
template <class V> double quickDistTo(const V &v) const { double dx=fabs((v.x()-x()).asDouble()),
dy=fabs((v.y()-y()).asDouble());
return (dx>dy)? (dx+dy/2): (dy+dx/2); }
// serial.
void serial(NLMISC::IStream &i) { i.serial(_x,_y); }
std::string toString() const { return NLMISC::toString("(%.3f,%.3f)",_x.asDouble(),_y.asDouble() ); }
private: // Attributes.
CAICoord _x, _y;
};
#endif