📄 vector2d.h
字号:
#ifndef S2DVECTOR_H
#define S2DVECTOR_H
//------------------------------------------------------------------------
//
// Name: Vector2D.h
//
// Desc: 2D vector struct
//
// Author: Mat Buckland (fup@ai-junkie.com)
//
//------------------------------------------------------------------------
#include <math.h>
#include <iosfwd>
#include <limits>
#include "utils.h"
struct Vector2D
{
double x;
double y;
Vector2D():x(0.0),y(0.0){}
Vector2D(double a, double b):x(a),y(b){}
//sets x and y to zero
void Zero(){x=0.0; y=0.0;}
//returns true if both x and y are zero
bool isZero()const{return (x*x + y*y) < MinDouble;}
//returns the length of the vector
inline double Length()const;
//returns the squared length of the vector (thereby avoiding the sqrt)
inline double LengthSq()const;
inline void Normalize();
inline double Dot(const Vector2D& v2)const;
//returns positive if v2 is clockwise of this vector,
//negative if anticlockwise (assuming the Y axis is pointing down,
//X axis to right like a Window app)
inline int Sign(const Vector2D& v2)const;
//returns the vector that is perpendicular to this one.
inline Vector2D Perp()const;
//adjusts x and y so that the length of the vector does not exceed max
inline void Truncate(double max);
//returns the distance between this vector and th one passed as a parameter
inline double Distance(const Vector2D &v2)const;
//squared version of above.
inline double DistanceSq(const Vector2D &v2)const;
inline void Reflect(const Vector2D& norm);
//returns the vector that is the reverse of this vector
inline Vector2D GetReverse()const;
//we need some overloaded operators
const Vector2D& operator+=(const Vector2D &rhs)
{
x += rhs.x;
y += rhs.y;
return *this;
}
const Vector2D& operator-=(const Vector2D &rhs)
{
x -= rhs.x;
y -= rhs.y;
return *this;
}
const Vector2D& operator*=(const double& rhs)
{
x *= rhs;
y *= rhs;
return *this;
}
const Vector2D& operator/=(const double& rhs)
{
x /= rhs;
y /= rhs;
return *this;
}
bool operator==(const Vector2D& rhs)const
{
return (isEqual(x, rhs.x) && isEqual(y,rhs.y) );
}
bool operator!=(const Vector2D& rhs)const
{
return (x != rhs.x) || (y != rhs.y);
}
};
//-----------------------------------------------------------------------some more operator overloads
inline Vector2D operator*(const Vector2D &lhs, double rhs);
inline Vector2D operator*(double lhs, const Vector2D &rhs);
inline Vector2D operator-(const Vector2D &lhs, const Vector2D &rhs);
inline Vector2D operator+(const Vector2D &lhs, const Vector2D &rhs);
inline Vector2D operator/(const Vector2D &lhs, double val);
std::ostream& operator<<(std::ostream& os, const Vector2D& rhs);
std::ifstream& operator>>(std::ifstream& is, Vector2D& lhs);
//------------------------------------------------------------------------member functions
//------------------------- Length ---------------------------------------
//
// returns the length of a 2D vector
//------------------------------------------------------------------------
inline double Vector2D::Length()const
{
return sqrt(x * x + y * y);
}
//------------------------- LengthSq -------------------------------------
//
// returns the squared length of a 2D vector
//------------------------------------------------------------------------
inline double Vector2D::LengthSq()const
{
return (x * x + y * y);
}
//------------------------- Vec2DDot -------------------------------------
//
// calculates the dot product
//------------------------------------------------------------------------
inline double Vector2D::Dot(const Vector2D &v2)const
{
return x*v2.x + y*v2.y;
}
//------------------------ Sign ------------------------------------------
//
// returns positive if v2 is clockwise of this vector,
// minus if anticlockwise (Y axis pointing down, X axis to right)
//------------------------------------------------------------------------
enum {clockwise = 1, anticlockwise = -1};
inline int Vector2D::Sign(const Vector2D& v2)const
{
if (y*v2.x > x*v2.y)
{
return anticlockwise;
}
else
{
return clockwise;
}
}
//------------------------------ Perp ------------------------------------
//
// Returns a vector perpendicular to this vector
//------------------------------------------------------------------------
inline Vector2D Vector2D::Perp()const
{
return Vector2D(-y, x);
}
//------------------------------ Distance --------------------------------
//
// calculates the euclidean distance between two vectors
//------------------------------------------------------------------------
inline double Vector2D::Distance(const Vector2D &v2)const
{
double ySeparation = v2.y - y;
double xSeparation = v2.x - x;
return sqrt(ySeparation*ySeparation + xSeparation*xSeparation);
}
//------------------------------ DistanceSq ------------------------------
//
// calculates the euclidean distance squared between two vectors
//------------------------------------------------------------------------
inline double Vector2D::DistanceSq(const Vector2D &v2)const
{
double ySeparation = v2.y - y;
double xSeparation = v2.x - x;
return ySeparation*ySeparation + xSeparation*xSeparation;
}
//----------------------------- Truncate ---------------------------------
//
// truncates a vector so that its length does not exceed max
//------------------------------------------------------------------------
inline void Vector2D::Truncate(double max)
{
if (this->Length() > max)
{
this->Normalize();
*this *= max;
}
}
//--------------------------- Reflect ------------------------------------
//
// given a normalized vector this method reflects the vector it
// is operating upon. (like the path of a ball bouncing off a wall)
//------------------------------------------------------------------------
inline void Vector2D::Reflect(const Vector2D& norm)
{
*this += 2.0 * this->Dot(norm) * norm.GetReverse();
}
//----------------------- GetReverse ----------------------------------------
//
// returns the vector that is the reverse of this vector
//------------------------------------------------------------------------
inline Vector2D Vector2D::GetReverse()const
{
return Vector2D(-this->x, -this->y);
}
//------------------------- Normalize ------------------------------------
//
// normalizes a 2D Vector
//------------------------------------------------------------------------
inline void Vector2D::Normalize()
{
double vector_length = this->Length();
if (vector_length > std::numeric_limits<double>::epsilon())
{
this->x /= vector_length;
this->y /= vector_length;
}
}
//------------------------------------------------------------------------non member functions
inline Vector2D Vec2DNormalize(const Vector2D &v)
{
Vector2D vec = v;
double vector_length = vec.Length();
if (vector_length > std::numeric_limits<double>::epsilon())
{
vec.x /= vector_length;
vec.y /= vector_length;
}
return vec;
}
inline double Vec2DDistance(const Vector2D &v1, const Vector2D &v2)
{
double ySeparation = v2.y - v1.y;
double xSeparation = v2.x - v1.x;
return sqrt(ySeparation*ySeparation + xSeparation*xSeparation);
}
inline double Vec2DDistanceSq(const Vector2D &v1, const Vector2D &v2)
{
double ySeparation = v2.y - v1.y;
double xSeparation = v2.x - v1.x;
return ySeparation*ySeparation + xSeparation*xSeparation;
}
inline double Vec2DLength(const Vector2D& v)
{
return sqrt(v.x*v.x + v.y*v.y);
}
inline double Vec2DLengthSq(const Vector2D& v)
{
return (v.x*v.x + v.y*v.y);
}
/*
inline Vector2D POINTStoVector(const POINTS & p)
{
return Vector2D(p.x, p.y);
}
inline Vector2D POINTtoVector(const POINT& p)
{
return Vector2D((double)p.x, (double)p.y);
}
inline POINTS VectorToPOINTS(const Vector2D& v)
{
POINTS p;
p.x = (short)v.x;
p.y = (short)v.y;
return p;
}
inline POINT VectorToPOINT(const Vector2D& v)
{
POINT p;
p.x = (long)v.x;
p.y = (long)v.y;
return p;
}
*/
//------------------------------------------------------------------------operator overloads
inline Vector2D operator*(const Vector2D &lhs, double rhs)
{
Vector2D result(lhs);
result *= rhs;
return result;
}
inline Vector2D operator*(double lhs, const Vector2D &rhs)
{
Vector2D result(rhs);
result *= lhs;
return result;
}
//overload the - operator
inline Vector2D operator-(const Vector2D &lhs, const Vector2D &rhs)
{
Vector2D result(lhs);
result.x -= rhs.x;
result.y -= rhs.y;
return result;
}
//overload the + operator
inline Vector2D operator+(const Vector2D &lhs, const Vector2D &rhs)
{
Vector2D result(lhs);
result.x += rhs.x;
result.y += rhs.y;
return result;
}
//overload the / operator
inline Vector2D operator/(const Vector2D &lhs, double val)
{
Vector2D result(lhs);
result.x /= val;
result.y /= val;
return result;
}
///////////////////////////////////////////////////////////////////////////////
//treats a window as a toroid
inline void WrapAround(Vector2D &pos, int MaxX, int MaxY)
{
if (pos.x > MaxX) {pos.x = 0.0;}
if (pos.x < 0) {pos.x = (double)MaxX;}
if (pos.y < 0) {pos.y = (double)MaxY;}
if (pos.y > MaxY) {pos.y = 0.0;}
}
//returns true if the point p is not inside the region defined by top_left
//and bot_rgt
inline bool NotInsideRegion(Vector2D p,
Vector2D top_left,
Vector2D bot_rgt)
{
return (p.x < top_left.x) || (p.x > bot_rgt.x) ||
(p.y < top_left.y) || (p.y > bot_rgt.y);
}
inline bool InsideRegion(Vector2D p,
Vector2D top_left,
Vector2D bot_rgt)
{
return !((p.x < top_left.x) || (p.x > bot_rgt.x) ||
(p.y < top_left.y) || (p.y > bot_rgt.y));
}
inline bool InsideRegion(Vector2D p, int left, int top, int right, int bottom)
{
return !( (p.x < left) || (p.x > right) || (p.y < top) || (p.y > bottom) );
}
//------------------ isSecondInFOVOfFirst -------------------------------------
//
// returns true if the target position is in the field of view of the entity
// positioned at posFirst facing in facingFirst
//-----------------------------------------------------------------------------
inline bool isSecondInFOVOfFirst(Vector2D posFirst,
Vector2D facingFirst,
Vector2D posSecond,
double fov)
{
Vector2D toTarget = Vec2DNormalize(posSecond - posFirst);
return facingFirst.Dot(toTarget) >= cos(fov/2.0);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -