2d向量
This commit is contained in:
parent
c8b1414fca
commit
83cb70bec9
@ -12,13 +12,18 @@
|
|||||||
#include <simgear/math/simd.hxx>
|
#include <simgear/math/simd.hxx>
|
||||||
|
|
||||||
/// 2D Vector Class
|
/// 2D Vector Class
|
||||||
|
//SGVec2类是一个2D向量类,定义了2D向量的基本操作和运算
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class SGVec2 {
|
class SGVec2 {
|
||||||
public:
|
public:
|
||||||
|
//定义一个类型别名value_type,表示向量中的元素类型
|
||||||
|
// C++11可以使用 using value_type = T;
|
||||||
typedef T value_type;
|
typedef T value_type;
|
||||||
|
|
||||||
/// Default constructor. Does not initialize at all.
|
/// Default constructor. Does not initialize at all.
|
||||||
/// If you need them zero initialized, use SGVec2::zeros()
|
/// If you need them zero initialized, use SGVec2::zeros()
|
||||||
|
//默认构造函数,不进行初始化
|
||||||
|
//如果需要零初始化,可以使用SGVec2::zeros()
|
||||||
SGVec2(void)
|
SGVec2(void)
|
||||||
{
|
{
|
||||||
/// Initialize with nans in the debug build, that will guarantee to have
|
/// Initialize with nans in the debug build, that will guarantee to have
|
||||||
@ -30,84 +35,110 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/// Constructor. Initialize by the given values
|
/// Constructor. Initialize by the given values
|
||||||
|
//构造函数,初始化为给定的值
|
||||||
SGVec2(T x, T y)
|
SGVec2(T x, T y)
|
||||||
{ _data = simd4_t<T,2>(x, y); }
|
{ _data = simd4_t<T,2>(x, y); }
|
||||||
/// Constructor. Initialize by the content of a plain array,
|
/// Constructor. Initialize by the content of a plain array,
|
||||||
/// make sure it has at least 2 elements
|
/// make sure it has at least 2 elements
|
||||||
|
//构造函数,使用一个包含2个元素的数组初始化
|
||||||
|
//确保数组至少有2个元素
|
||||||
explicit SGVec2(const T* d)
|
explicit SGVec2(const T* d)
|
||||||
{ _data = d ? simd4_t<T,2>(d) : simd4_t<T,2>(T(0)); }
|
{ _data = d ? simd4_t<T,2>(d) : simd4_t<T,2>(T(0)); }
|
||||||
|
//模板构造函数,使用另一个SGVec2<S>类型的二维向量初始化
|
||||||
template<typename S>
|
template<typename S>
|
||||||
explicit SGVec2(const SGVec2<S>& d)
|
explicit SGVec2(const SGVec2<S>& d)
|
||||||
{ data()[0] = d[0]; data()[1] = d[1]; }
|
{ data()[0] = d[0]; data()[1] = d[1]; }
|
||||||
|
|
||||||
/// Access by index, the index is unchecked
|
/// Access by index, the index is unchecked
|
||||||
|
//小括号运算符重载,通过索引访问向量元素的常量引用,索引未检查
|
||||||
const T& operator()(unsigned i) const
|
const T& operator()(unsigned i) const
|
||||||
{ return data()[i]; }
|
{ return data()[i]; }
|
||||||
/// Access by index, the index is unchecked
|
/// Access by index, the index is unchecked
|
||||||
|
//小括号运算符重载,通过索引访问向量元素的引用,索引未检查
|
||||||
T& operator()(unsigned i)
|
T& operator()(unsigned i)
|
||||||
{ return data()[i]; }
|
{ return data()[i]; }
|
||||||
|
|
||||||
/// Access raw data by index, the index is unchecked
|
/// Access raw data by index, the index is unchecked
|
||||||
|
//中括号运算符重载,通过索引访问向量元素的常量引用,索引未检查
|
||||||
const T& operator[](unsigned i) const
|
const T& operator[](unsigned i) const
|
||||||
{ return data()[i]; }
|
{ return data()[i]; }
|
||||||
/// Access raw data by index, the index is unchecked
|
/// Access raw data by index, the index is unchecked
|
||||||
|
//中括号运算符重载,通过索引访问向量元素的引用,索引未检查
|
||||||
T& operator[](unsigned i)
|
T& operator[](unsigned i)
|
||||||
{ return data()[i]; }
|
{ return data()[i]; }
|
||||||
|
|
||||||
/// Access the x component
|
/// Access the x component
|
||||||
|
//x()函数,返回向量的x分量的常量引用
|
||||||
const T& x(void) const
|
const T& x(void) const
|
||||||
{ return data()[0]; }
|
{ return data()[0]; }
|
||||||
/// Access the x component
|
/// Access the x component
|
||||||
|
//x()函数,返回向量的x分量的引用
|
||||||
T& x(void)
|
T& x(void)
|
||||||
{ return data()[0]; }
|
{ return data()[0]; }
|
||||||
/// Access the y component
|
/// Access the y component
|
||||||
|
//y()函数,返回向量的y分量的常量引用
|
||||||
const T& y(void) const
|
const T& y(void) const
|
||||||
{ return data()[1]; }
|
{ return data()[1]; }
|
||||||
/// Access the y component
|
/// Access the y component
|
||||||
|
//y()函数,返回向量的y分量的引用
|
||||||
T& y(void)
|
T& y(void)
|
||||||
{ return data()[1]; }
|
{ return data()[1]; }
|
||||||
|
|
||||||
/// Access raw data
|
/// Access raw data
|
||||||
|
//返回一个实际数组的常量引用,是一个2个元素的数组
|
||||||
const T (&data(void) const)[2]
|
const T (&data(void) const)[2]
|
||||||
{ return _data.ptr(); }
|
{ return _data.ptr(); }
|
||||||
/// Access raw data
|
/// Access raw data
|
||||||
|
//返回一个实际数组的引用,是一个2个元素的数组
|
||||||
T (&data(void))[2]
|
T (&data(void))[2]
|
||||||
{ return _data.ptr(); }
|
{ return _data.ptr(); }
|
||||||
|
//返回一个simd4_t<T,2>类型的常量引用,表示一个2D向量
|
||||||
const simd4_t<T,2> &simd2(void) const
|
const simd4_t<T,2> &simd2(void) const
|
||||||
{ return _data; }
|
{ return _data; }
|
||||||
/// Readonly raw storage interface
|
/// Readonly raw storage interface
|
||||||
|
//返回一个simd4_t<T,2>类型的引用,表示一个2D向量
|
||||||
simd4_t<T,2> &simd2(void)
|
simd4_t<T,2> &simd2(void)
|
||||||
{ return _data; }
|
{ return _data; }
|
||||||
|
|
||||||
/// Inplace addition
|
/// Inplace addition
|
||||||
|
//+=运算符重载,实现向量加法
|
||||||
SGVec2& operator+=(const SGVec2& v)
|
SGVec2& operator+=(const SGVec2& v)
|
||||||
{ _data += v.simd2(); return *this; }
|
{ _data += v.simd2(); return *this; }
|
||||||
/// Inplace subtraction
|
/// Inplace subtraction
|
||||||
|
//-=运算符重载,实现向量减法
|
||||||
SGVec2& operator-=(const SGVec2& v)
|
SGVec2& operator-=(const SGVec2& v)
|
||||||
{ _data -= v.simd2(); return *this; }
|
{ _data -= v.simd2(); return *this; }
|
||||||
/// Inplace scalar multiplication
|
/// Inplace scalar multiplication
|
||||||
|
//*=运算符重载,实现向量乘法
|
||||||
template<typename S>
|
template<typename S>
|
||||||
SGVec2& operator*=(S s)
|
SGVec2& operator*=(S s)
|
||||||
{ _data *= s; return *this; }
|
{ _data *= s; return *this; }
|
||||||
/// Inplace scalar multiplication by 1/s
|
/// Inplace scalar multiplication by 1/s
|
||||||
|
// /=运算符重载,实现向量除法
|
||||||
template<typename S>
|
template<typename S>
|
||||||
SGVec2& operator/=(S s)
|
SGVec2& operator/=(S s)
|
||||||
{ _data*=(1/T(s)); return *this; }
|
{ _data*=(1/T(s)); return *this; }
|
||||||
|
|
||||||
/// Return an all zero vector
|
/// Return an all zero vector
|
||||||
|
//zeros()函数,返回一个零向量
|
||||||
static SGVec2 zeros(void)
|
static SGVec2 zeros(void)
|
||||||
{ return SGVec2(0, 0); }
|
{ return SGVec2(0, 0); }
|
||||||
/// Return unit vectors
|
/// Return unit vectors
|
||||||
|
//e1()函数,返回一个x=1,y=0的向量
|
||||||
static SGVec2 e1(void)
|
static SGVec2 e1(void)
|
||||||
{ return SGVec2(1, 0); }
|
{ return SGVec2(1, 0); }
|
||||||
|
//e2()函数,返回一个x=0,y=1的向量
|
||||||
static SGVec2 e2(void)
|
static SGVec2 e2(void)
|
||||||
{ return SGVec2(0, 1); }
|
{ return SGVec2(0, 1); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
//_data是一个simd4_t<T,2>类型的成员变量,表示一个2D向量
|
||||||
simd4_t<T,2> _data;
|
simd4_t<T,2> _data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 以下是一些运算符的类外重载
|
||||||
/// Unary +, do nothing ...
|
/// Unary +, do nothing ...
|
||||||
|
//一元+运算符重载,什么都不做
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
const SGVec2<T>&
|
const SGVec2<T>&
|
||||||
@ -115,6 +146,7 @@ operator+(const SGVec2<T>& v)
|
|||||||
{ return v; }
|
{ return v; }
|
||||||
|
|
||||||
/// Unary -, do nearly nothing
|
/// Unary -, do nearly nothing
|
||||||
|
//一元-运算符重载,对向量取反[-x,-y]
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
SGVec2<T>
|
SGVec2<T>
|
||||||
@ -122,6 +154,7 @@ operator-(SGVec2<T> v)
|
|||||||
{ v *= -1; return v; }
|
{ v *= -1; return v; }
|
||||||
|
|
||||||
/// Binary +
|
/// Binary +
|
||||||
|
//二元+运算符重载,实现向量加法[x1+x2,y1+y2]
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
SGVec2<T>
|
SGVec2<T>
|
||||||
@ -129,6 +162,7 @@ operator+(SGVec2<T> v1, const SGVec2<T>& v2)
|
|||||||
{ v1.simd2() += v2.simd2(); return v1; }
|
{ v1.simd2() += v2.simd2(); return v1; }
|
||||||
|
|
||||||
/// Binary -
|
/// Binary -
|
||||||
|
//二元-运算符重载,实现向量减法[x1-x2,y1-y2]
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
SGVec2<T>
|
SGVec2<T>
|
||||||
@ -136,6 +170,7 @@ operator-(SGVec2<T> v1, const SGVec2<T>& v2)
|
|||||||
{ v1.simd2() -= v2.simd2(); return v1; }
|
{ v1.simd2() -= v2.simd2(); return v1; }
|
||||||
|
|
||||||
/// Scalar multiplication
|
/// Scalar multiplication
|
||||||
|
//标量乘法运算符重载,实现向量左数乘[s*x1,s*y1]
|
||||||
template<typename S, typename T>
|
template<typename S, typename T>
|
||||||
inline
|
inline
|
||||||
SGVec2<T>
|
SGVec2<T>
|
||||||
@ -143,6 +178,7 @@ operator*(S s, SGVec2<T> v)
|
|||||||
{ v.simd2() *= s; return v; }
|
{ v.simd2() *= s; return v; }
|
||||||
|
|
||||||
/// Scalar multiplication
|
/// Scalar multiplication
|
||||||
|
//标量乘法运算符重载,实现向量右数乘[x1*s,y1*s]
|
||||||
template<typename S, typename T>
|
template<typename S, typename T>
|
||||||
inline
|
inline
|
||||||
SGVec2<T>
|
SGVec2<T>
|
||||||
@ -152,6 +188,9 @@ operator*(SGVec2<T> v, S s)
|
|||||||
/// multiplication as a multiplicator, that is assume that the first vector
|
/// multiplication as a multiplicator, that is assume that the first vector
|
||||||
/// represents a 2x2 diagonal matrix with the diagonal elements in the vector.
|
/// represents a 2x2 diagonal matrix with the diagonal elements in the vector.
|
||||||
/// Then the result is the product of that matrix times the second vector.
|
/// Then the result is the product of that matrix times the second vector.
|
||||||
|
/// 作为乘数的乘法运算,即假设第一个向量
|
||||||
|
/// 表示一个2x2的对角矩阵,其对角线元素就是向量中的元素。
|
||||||
|
/// 然后结果是该矩阵与第二个向量的乘积。即向量对应位置相乘[x1*x2,y1*y2]
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
SGVec2<T>
|
SGVec2<T>
|
||||||
@ -159,16 +198,21 @@ mult(SGVec2<T> v1, const SGVec2<T>& v2)
|
|||||||
{ v1.simd2() *= v2.simd2(); return v1; }
|
{ v1.simd2() *= v2.simd2(); return v1; }
|
||||||
|
|
||||||
/// component wise min
|
/// component wise min
|
||||||
|
//向量分量求最小值运算,实现向量分量最小值运算[min(x1,x2),min(y1,y2)]
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
SGVec2<T>
|
SGVec2<T>
|
||||||
min(SGVec2<T> v1, const SGVec2<T>& v2)
|
min(SGVec2<T> v1, const SGVec2<T>& v2)
|
||||||
{ v1.simd2() = simd4::min(v1.simd2(), v2.simd2()); return v1; }
|
{ v1.simd2() = simd4::min(v1.simd2(), v2.simd2()); return v1; }
|
||||||
|
|
||||||
|
//向量分量与右侧标量求最小值运算,实现向量分量与标量最小值运算[min(x,s),min(y,s)]
|
||||||
template<typename S, typename T>
|
template<typename S, typename T>
|
||||||
inline
|
inline
|
||||||
SGVec2<T>
|
SGVec2<T>
|
||||||
min(SGVec2<T> v, S s)
|
min(SGVec2<T> v, S s)
|
||||||
{ v.simd2() = simd4::min(v.simd2(), simd4_t<T,2>(s)); return v; }
|
{ v.simd2() = simd4::min(v.simd2(), simd4_t<T,2>(s)); return v; }
|
||||||
|
|
||||||
|
//向量分量与左侧标量求最小值运算,实现向量分量与标量最小值运算[min(s,x),min(s,y)]
|
||||||
template<typename S, typename T>
|
template<typename S, typename T>
|
||||||
inline
|
inline
|
||||||
SGVec2<T>
|
SGVec2<T>
|
||||||
@ -176,16 +220,21 @@ min(S s, SGVec2<T> v)
|
|||||||
{ v.sim2() = simd4::min(v.simd2(), simd4_t<T,2>(s)); return v; }
|
{ v.sim2() = simd4::min(v.simd2(), simd4_t<T,2>(s)); return v; }
|
||||||
|
|
||||||
/// component wise max
|
/// component wise max
|
||||||
|
//向量分量求最大值运算,实现向量分量最大值运算[max(x1,x2),max(y1,y2)]
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
SGVec2<T>
|
SGVec2<T>
|
||||||
max(SGVec2<T> v1, const SGVec2<T>& v2)
|
max(SGVec2<T> v1, const SGVec2<T>& v2)
|
||||||
{ v1.simd2() = simd4::max(v1.simd2(), v2.simd2()); return v1; }
|
{ v1.simd2() = simd4::max(v1.simd2(), v2.simd2()); return v1; }
|
||||||
|
|
||||||
|
//向量分量与右侧标量求最大值运算,实现向量分量与标量最大值运算[max(x,s),max(y,s)]
|
||||||
template<typename S, typename T>
|
template<typename S, typename T>
|
||||||
inline
|
inline
|
||||||
SGVec2<T>
|
SGVec2<T>
|
||||||
max(const SGVec2<T>& v, S s)
|
max(const SGVec2<T>& v, S s)
|
||||||
{ v = simd4::max(v.simd2(), simd4_t<T,2>(s)); return v; }
|
{ v = simd4::max(v.simd2(), simd4_t<T,2>(s)); return v; }
|
||||||
|
|
||||||
|
//向量分量与左侧标量求最大值运算,实现向量分量与标量最大值运算[max(s,x),max(s,y)]
|
||||||
template<typename S, typename T>
|
template<typename S, typename T>
|
||||||
inline
|
inline
|
||||||
SGVec2<T>
|
SGVec2<T>
|
||||||
@ -194,6 +243,7 @@ max(S s, const SGVec2<T>& v)
|
|||||||
|
|
||||||
/// Add two vectors taking care of (integer) overflows. The values are limited
|
/// Add two vectors taking care of (integer) overflows. The values are limited
|
||||||
/// to the respective minimum and maximum values.
|
/// to the respective minimum and maximum values.
|
||||||
|
//向量分量无溢出求和运算,实现向量分量求和[x1+x2,y1+y2]
|
||||||
template<class T>
|
template<class T>
|
||||||
SGVec2<T> addClipOverflow(SGVec2<T> const& lhs, SGVec2<T> const& rhs)
|
SGVec2<T> addClipOverflow(SGVec2<T> const& lhs, SGVec2<T> const& rhs)
|
||||||
{
|
{
|
||||||
@ -204,6 +254,7 @@ SGVec2<T> addClipOverflow(SGVec2<T> const& lhs, SGVec2<T> const& rhs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Scalar dot product
|
/// Scalar dot product
|
||||||
|
//向量点积运算,实现向量点积运算 x1*x2+y1*y2
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
T
|
T
|
||||||
@ -211,6 +262,7 @@ dot(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
|||||||
{ return simd4::dot(v1.simd2(), v2.simd2()); }
|
{ return simd4::dot(v1.simd2(), v2.simd2()); }
|
||||||
|
|
||||||
/// The euclidean norm of the vector, that is what most people call length
|
/// The euclidean norm of the vector, that is what most people call length
|
||||||
|
//向量二范数运算,实现向量二范数运算 sqrt(x^2+y^2)
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
T
|
T
|
||||||
@ -219,6 +271,7 @@ norm(const SGVec2<T>& v)
|
|||||||
|
|
||||||
/// The squared euclidean norm of the vector
|
/// The squared euclidean norm of the vector
|
||||||
/// Comparing two squared values prevents two computionally heavy sqrt calls.
|
/// Comparing two squared values prevents two computionally heavy sqrt calls.
|
||||||
|
//向量二范数平方运算,实现向量二范数平方运算 (x^2+y^2)
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
T
|
T
|
||||||
@ -226,6 +279,7 @@ norm2(const SGVec2<T>& v)
|
|||||||
{ return simd4::magnitude2(v.simd2()); }
|
{ return simd4::magnitude2(v.simd2()); }
|
||||||
|
|
||||||
/// The euclidean norm of the vector, that is what most people call length
|
/// The euclidean norm of the vector, that is what most people call length
|
||||||
|
//向量长度运算,实现向量长度运算,与二范数相同 sqrt(x^2+y^2)
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
T
|
T
|
||||||
@ -234,6 +288,7 @@ length(const SGVec2<T>& v)
|
|||||||
|
|
||||||
/// The 1-norm of the vector, this one is the fastest length function we
|
/// The 1-norm of the vector, this one is the fastest length function we
|
||||||
/// can implement on modern cpu's
|
/// can implement on modern cpu's
|
||||||
|
//向量一范数运算,实现向量一范数运算 |x|+|y|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
T
|
T
|
||||||
@ -241,6 +296,7 @@ norm1(SGVec2<T> v)
|
|||||||
{ v.simd2() = simd4::abs(v.simd2()); return (v(0)+v(1)); }
|
{ v.simd2() = simd4::abs(v.simd2()); return (v(0)+v(1)); }
|
||||||
|
|
||||||
/// The inf-norm of the vector
|
/// The inf-norm of the vector
|
||||||
|
//向量无穷范数运算,实现向量无穷范数运算 max(|x|,|y|)
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
T
|
T
|
||||||
@ -251,6 +307,7 @@ normI(SGVec2<T> v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The euclidean norm of the vector, that is what most people call length
|
/// The euclidean norm of the vector, that is what most people call length
|
||||||
|
//向量归一化运算,实现向量归一化运算,即向量除以其长度 [x/sqrt(x^2+y^2),y/sqrt(x^2+y^2)]
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
SGVec2<T>
|
SGVec2<T>
|
||||||
@ -263,6 +320,7 @@ normalize(const SGVec2<T>& v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Return true if exactly the same
|
/// Return true if exactly the same
|
||||||
|
//向量相等判断运算符重载,实现向量相等判断 x1==x2 && y1==y2
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
@ -270,6 +328,7 @@ operator==(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
|||||||
{ return v1(0) == v2(0) && v1(1) == v2(1); }
|
{ return v1(0) == v2(0) && v1(1) == v2(1); }
|
||||||
|
|
||||||
/// Return true if not exactly the same
|
/// Return true if not exactly the same
|
||||||
|
//向量不相等判断运算符重载,实现向量不相等判断 x1!=x2 || y1!=y2
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
@ -277,6 +336,7 @@ operator!=(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
|||||||
{ return ! (v1 == v2); }
|
{ return ! (v1 == v2); }
|
||||||
|
|
||||||
/// Return true if smaller, good for putting that into a std::map
|
/// Return true if smaller, good for putting that into a std::map
|
||||||
|
//向量小于判断运算符重载,实现向量小于判断 x1<x2 || (x1==x2 && y1<y2)
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
@ -287,6 +347,7 @@ operator<(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
|||||||
else return (v1(1) < v2(1));
|
else return (v1(1) < v2(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//向量小于等于判断运算符重载,实现向量小于等于判断 x1<=x2 || (x1==x2 && y1<=y2)
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
@ -297,12 +358,14 @@ operator<=(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
|||||||
else return (v1(1) <= v2(1));
|
else return (v1(1) <= v2(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//向量大于判断运算符重载,实现向量大于判断 x1>x2 || (x1==x2 && y1>y2)
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
operator>(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
operator>(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
||||||
{ return operator<(v2, v1); }
|
{ return operator<(v2, v1); }
|
||||||
|
|
||||||
|
//向量大于等于判断运算符重载,实现向量大于等于判断 x1>=x2 || (x1==x2 && y1>=y2)
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
@ -310,6 +373,14 @@ operator>=(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
|||||||
{ return operator<=(v2, v1); }
|
{ return operator<=(v2, v1); }
|
||||||
|
|
||||||
/// Return true if equal to the relative tolerance tol
|
/// Return true if equal to the relative tolerance tol
|
||||||
|
// 判断两个二维向量是否在给定误差范围内相等,
|
||||||
|
// rtol: 相对误差容限(relative tolerance)
|
||||||
|
// atol: 绝对误差容限(absolute tolerance)
|
||||||
|
// 这种比较方式特别适用于:
|
||||||
|
// 1. 处理浮点数计算中的舍入误差
|
||||||
|
// 2. 当向量的分量值很大时,允许有更大的绝对误差(通过相对误差项)
|
||||||
|
// 3. 当向量的分量值很小时,通过绝对误差项来避免过于严格的比较
|
||||||
|
// 这比简单的相等比较(==)更实用,因为在计算机的浮点数运算中,由于舍入误差,很少有两个浮点数完全相等的情况。
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
@ -317,6 +388,9 @@ equivalent(const SGVec2<T>& v1, const SGVec2<T>& v2, T rtol, T atol)
|
|||||||
{ return norm1(v1 - v2) < rtol*(norm1(v1) + norm1(v2)) + atol; }
|
{ return norm1(v1 - v2) < rtol*(norm1(v1) + norm1(v2)) + atol; }
|
||||||
|
|
||||||
/// Return true if equal to the relative tolerance tol
|
/// Return true if equal to the relative tolerance tol
|
||||||
|
// 判断两个二维向量是否在给定相对误差容限下相等,
|
||||||
|
// rtol: 相对误差容限(relative tolerance)
|
||||||
|
// 适用于不需要考虑绝对误差的场景
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
@ -324,6 +398,8 @@ equivalent(const SGVec2<T>& v1, const SGVec2<T>& v2, T rtol)
|
|||||||
{ return norm1(v1 - v2) < rtol*(norm1(v1) + norm1(v2)); }
|
{ return norm1(v1 - v2) < rtol*(norm1(v1) + norm1(v2)); }
|
||||||
|
|
||||||
/// Return true if about equal to roundoff of the underlying type
|
/// Return true if about equal to roundoff of the underlying type
|
||||||
|
// 判断两个二维向量是否在默认的绝对误差容限和相对误差容限下相等,
|
||||||
|
// 默认绝对误差容限和默认相对误差容限为100倍的机器精度epsilon
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
@ -334,6 +410,7 @@ equivalent(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The euclidean distance of the two vectors
|
/// The euclidean distance of the two vectors
|
||||||
|
// 计算两个二维向量之间的欧几里得距离 sqrt((x1-x2)^2+(y1-y2)^2)
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
T
|
T
|
||||||
@ -341,6 +418,7 @@ dist(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
|||||||
{ return simd4::magnitude(v1.simd2() - v2.simd2()); }
|
{ return simd4::magnitude(v1.simd2() - v2.simd2()); }
|
||||||
|
|
||||||
/// The squared euclidean distance of the two vectors
|
/// The squared euclidean distance of the two vectors
|
||||||
|
// 计算两个二维向量之间的欧几里得距离的平方 (x1-x2)^2+(y1-y2)^2
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
T
|
T
|
||||||
@ -348,6 +426,9 @@ distSqr(SGVec2<T> v1, const SGVec2<T>& v2)
|
|||||||
{ return simd4::magnitude2(v1.simd2() - v2.simd2()); }
|
{ return simd4::magnitude2(v1.simd2() - v2.simd2()); }
|
||||||
|
|
||||||
// calculate the projection of u along the direction of d.
|
// calculate the projection of u along the direction of d.
|
||||||
|
// 计算向量u在向量d方向上的投影 d * (dot(u, d) / norm2(d))
|
||||||
|
// 这里的判断SGLimits<T>::min() < denom应该有问题,为了避免除以0应该判断denom <= SGLimits<T>::min()
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
SGVec2<T>
|
SGVec2<T>
|
||||||
@ -355,10 +436,12 @@ projection(const SGVec2<T>& u, const SGVec2<T>& d)
|
|||||||
{
|
{
|
||||||
T denom = simd4::magnitude2(d.simd2());
|
T denom = simd4::magnitude2(d.simd2());
|
||||||
T ud = dot(u, d);
|
T ud = dot(u, d);
|
||||||
if (SGLimits<T>::min() < denom) return u;
|
//if (SGLimits<T>::min() < denom) return u;
|
||||||
|
if (denom <= SGLimits<T>::min()) return u; //这里改了一下
|
||||||
else return d * (dot(u, d) / denom);
|
else return d * (dot(u, d) / denom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 计算两个二维向量之间的线性插值,tau在[0,1]之间
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
SGVec2<T>
|
SGVec2<T>
|
||||||
@ -370,6 +453,11 @@ interpolate(T tau, const SGVec2<T>& v1, const SGVec2<T>& v2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helper function for point_in_triangle
|
// Helper function for point_in_triangle
|
||||||
|
// 用于计算三个点构成的有向面积(signed area),它是判断点是否在三角形内的辅助函数。
|
||||||
|
//正值:表示三个点按逆时针方向排列
|
||||||
|
//负值:表示三个点按顺时针方向排列
|
||||||
|
//零值:表示三点共线
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline
|
inline
|
||||||
T
|
T
|
||||||
@ -379,6 +467,10 @@ pt_determine(const SGVec2<T>& pt1, const SGVec2<T>& pt2, const SGVec2<T>& pt3)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Is testpt inside the triangle formed by the other three points?
|
// Is testpt inside the triangle formed by the other three points?
|
||||||
|
// 判断点testpt是否在三角形内
|
||||||
|
// 如果一个点在三角形内部,那么它与三角形任意两个顶点形成的有向面积的符号应该都相同(要么都是正的,要么都是负的)
|
||||||
|
// 如果一个点在三角形外部,那么它与三角形任意两个顶点形成的有向面积的符号应该相反(一个为正,一个为负)
|
||||||
|
// 如果一个点在三角形边上,那么它与三角形任意两个顶点形成的有向面积的符号应该为0
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
@ -392,6 +484,7 @@ point_in_triangle(const SGVec2<T>& testpt, const SGVec2<T>& pt1, const SGVec2<T>
|
|||||||
return !(has_neg && has_pos);
|
return !(has_neg && has_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 判断一个二维向量是否有NaN值
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
@ -401,17 +494,20 @@ isNaN(const SGVec2<T>& v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Output to an ostream
|
/// Output to an ostream
|
||||||
|
// 将二维向量输出到流中
|
||||||
template<typename char_type, typename traits_type, typename T>
|
template<typename char_type, typename traits_type, typename T>
|
||||||
inline
|
inline
|
||||||
std::basic_ostream<char_type, traits_type>&
|
std::basic_ostream<char_type, traits_type>&
|
||||||
operator<<(std::basic_ostream<char_type, traits_type>& s, const SGVec2<T>& v)
|
operator<<(std::basic_ostream<char_type, traits_type>& s, const SGVec2<T>& v)
|
||||||
{ return s << "[ " << v(0) << ", " << v(1) << " ]"; }
|
{ return s << "[ " << v(0) << ", " << v(1) << " ]"; }
|
||||||
|
|
||||||
|
// 将二维双精度浮点向量转换为单精度浮点型向量
|
||||||
inline
|
inline
|
||||||
SGVec2f
|
SGVec2f
|
||||||
toVec2f(const SGVec2d& v)
|
toVec2f(const SGVec2d& v)
|
||||||
{ SGVec2f f(v); return f; }
|
{ SGVec2f f(v); return f; }
|
||||||
|
|
||||||
|
// 将二维单精度浮点向量转换为双精度浮点型向量
|
||||||
inline
|
inline
|
||||||
SGVec2d
|
SGVec2d
|
||||||
toVec2d(const SGVec2f& v)
|
toVec2d(const SGVec2f& v)
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <simgear/math/SGLimits.hxx>
|
#include <simgear/math/SGLimits.hxx>
|
||||||
#include <simgear/math/SGMisc.hxx>
|
#include <simgear/math/SGMisc.hxx>
|
||||||
|
|
||||||
|
//预先声明simd4_t类
|
||||||
template<typename T, int N> class simd4_t;
|
template<typename T, int N> class simd4_t;
|
||||||
|
|
||||||
namespace simd4
|
namespace simd4
|
||||||
|
Loading…
x
Reference in New Issue
Block a user