【Irrlicht引擎 笔记】Core模块

irr::core

向量、平面、数组、列表等基础类都可以在这个命名空间中找到

irr::core::vector2d<T>

1.判断浮点数是否相等需要考虑'浮点数精度'问题

浮点数精度问题产生原因:二进制不能表示部分十进制数字,产生了数值丢失的问题。
float精度和范围参考地址

float的范围为-3.4×10^38 ~ 3.4×10^38,有效数字为7位,能保证正确的有6位
float.h中的宏定义:
#define FLT_EPSILON 1.192092896e-07F // smallest such that 1.0+FLT_EPSILON != 1.0
FLT_EPSILON为0.0000001192092896 这个是对于1.0+x而言最小误差是这个么大。
但是我这个输出为啥是不相等的啊...↓↓↓
img
算了先不纠结这个了。在Irricht中浮点数误差值定在0.000001f,应该是根据能保证正确的有效数字为6位来定的。

2.判断两二维向量是否(近似)平行

	//! check if this vector is parallel to another vector
	bool nearlyParallel( const vector2d<T> & other, const T factor = relativeErrorFactor<T>()) const
	{
		// https://eagergames.wordpress.com/2017/04/01/fast-parallel-lines-and-vectors-test/
		// if a || b then  a.x/a.y = b.x/b.y (similiar triangles)
		// if a || b then either both x are 0 or both y are 0.

		return  equalsRelative( X*other.Y, other.X* Y, factor)
		&& // a bit counterintuitive, but makes sure  that
		   // only y or only x are 0, and at same time deals
		   // with the case where one vector is zero vector.
			(X*other.X + Y*other.Y) != 0;
	}

这里判断斜率是否相等并且这两都不是零向量
其中判断斜率相等用的不是判断浮点数是否相等,而且另写了一个否近似相等函数:

	//! returns if a equals b, taking relative error in form of factor
	//! this particular function does not involve any division.
	template <class T>
	inline bool equalsRelative( const T a, const T b, const T factor = relativeErrorFactor<T>())
	{
		//https://eagergames.wordpress.com/2017/04/01/fast-parallel-lines-and-vectors-test/

		const T maxi = max_( a, b);
		const T mini = min_( a, b);
		const T maxMagnitude = max_( maxi, -mini);

		return	(maxMagnitude*factor + maxi) == (maxMagnitude*factor + mini); // MAD Wise
	}

这里用的判断相等方法是:取a和b和他们的倒数这四个数中最大的一个数作为基数x,在基数的基础上乘以一个因子f并且加上他们本身,即y1 = xf + a, y2 = xf + b,判断y1和y2是否相等。即用计算机浮点计算来判断误差是否可被消除,最终结果相等则a和b近似相等。

3.点绕着某点逆时针旋转 (二维)

根据已知变量联立方程求解,直接参考👉链接
Irrlicht做法应该与上面链接中一致,但做了优化 把旋转中心点平移到坐标原点计算:

	//! rotates the point anticlockwise around a center by an amount of degrees.
	/** \param degrees Amount of degrees to rotate by, anticlockwise.
	\param center Rotation center.
	\return This vector after transformation. */
	vector2d<T>& rotateBy(f64 degrees, const vector2d<T>& center=vector2d<T>())
	{
		degrees *= DEGTORAD64;
		const f64 cs = cos(degrees);
		const f64 sn = sin(degrees);

		X -= center.X;
		Y -= center.Y;

		set((T)(X*cs - Y*sn), (T)(X*sn + Y*cs));

		X += center.X;
		Y += center.Y;
		return *this;
	}

4.二次插值?(用处暂未看)

	//! Creates a quadratically interpolated vector between this and two other vectors.
	/** \param v2 Second vector to interpolate with.
	\param v3 Third vector to interpolate with (maximum at 1.0f)
	\param d Interpolation value between 0.0f (all this vector) and 1.0f (all the 3rd vector).
	Note that this is the opposite direction of interpolation to getInterpolated() and interpolate()
	\return An interpolated vector. This vector is not modified. */
	vector2d<T> getInterpolated_quadratic(const vector2d<T>& v2, const vector2d<T>& v3, f64 d) const
	{
		// this*(1-d)*(1-d) + 2 * v2 * (1-d) + v3 * d * d;
		const f64 inv = 1.0f - d;
		const f64 mul0 = inv * inv;
		const f64 mul1 = 2.0f * d * inv;
		const f64 mul2 = d * d;

		return vector2d<T> ( (T)(X * mul0 + v2.X * mul1 + v3.X * mul2),
					(T)(Y * mul0 + v2.Y * mul1 + v3.Y * mul2));
	}

5.判断三点是顺时针、逆时针、共线

已知a、b、c三点,求a->b->c是顺时针还是逆时针还是共线?
用了向量叉乘,ab向量 x bc向量,结果为'正'则是逆时针、'负'则是顺时针、'零'则共线

向量如何叉乘:
img
图片来自百度百科

irr::core::vector3d<T>

posted @ 2023-03-16 18:32  pupil337  阅读(24)  评论(0编辑  收藏  举报