分享

定点数运算数学库

 新用户0118F7lQ 2022-03-18

大纲如下:

图片
放大倍数 (举个简单例子,方便大家理解为什么要放大倍数)

  // 0.1 + 0.2 = 0.3;

  // 0.1 * 1000 = 100;

  // 0.2 * 1000 = 200;

  // 100 + 200 = 300;

 即是放大倍数的思路。

移位运算 (我们将浮点数即不是放大100倍,也不是放大1000倍,而是1024倍,即移位运算。为什么要用移位运算呢?因为它直接操作的是二进制数据,运算效率远远超过乘法运算,再者定点数运算库是基础类库,整个游戏中的运算是靠它支撑起来的,在底层做了这个优化,对于全局运算效率来说是会有大的提升的!)

位运算和移位运算-c#参考链接:https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/operators/bitwise-and-shift-operators

图片

定点数关系运算符、显式隐式转换 (主要就是对常规运算符(+-*/取反显隐式转换等)进行运算符重载处理了,来实现定点数的运算处理,没啥好细讲的,如下图)

图片

 
以上我们就实现了定点数的+-*/运算,但还是存在一些问题呢。如图:

图片

那问题是如何导致的呢?导致的原因就是在计算机中负数是用补码来表示的。emo,这就要来了解下移位操作原理啦。

图片

注:发现没有,实现了加法器就实现了全部(加减乘除)。想到用这一个方法来解决全部问题的计算机前辈,不得不令人敬佩,永远的神!基于此原理,我们在程序中规避对负数的处理问题不就解决了(将负数取反转化为正数来处理)。

确定性向量运算 (向量的常规运算(+-*/ 是否相等...)也是进行运算符重载处理来实现的,故没啥好细讲的)

定点向量平方根

   正常来说,我们求平方根,直接就用Mathf.Sqrt()即可。但我们是用这个定点数来求平方根,是不能直接使用这个api方法的,得自己来实现求平方根的过程。

 如何求呢?emo,是用牛顿迭代法来求平方根的,如图

图片

定点向量规格化

  这个相对来说比较简单了,原理:用向量PEInt.one(即(1,1,1))去除以当前向量,获得一个比值,然后将当前向量去乘以这个比值,即可获得当前定点向量的单位向量了。

定点向量点乘与叉乘

 向量点乘(内积),又称数量积或标量积。

 从代数角度看,点积是对两个向量对应位置上的值相乘再相加的操作,其结果即为点积。

 从几何角度看,点积是两个向量的长度与它们夹角余弦的积。

图片

  几何意义 :点乘的结果表示向量b 在 向量a 方向上的投影 与 向量b长度 的乘积,反映了两个向量的相似度,结果越大越相似。基于结果可以判断这两个向量是否是同一方向,是否正交垂直,如图。

图片

向量叉乘(外积),又称向量积。

图片

几何意义:如果以向量a 和 向量b 为边构成一个平行四边形,那么这两个向量外积的模长为这个平行四边形的面积。

计算定点向量夹角

  点乘代数定义推导几何定义(常用来求向量夹角),三角形AOB中,余弦定理及推导合并得:

图片

接下来,就是进行反余弦函数计算,如何计算呢、emo,先来看看反余弦函数,如图

图片

反余弦函数级数映射查表

通过上面的函数图像,然后我们放大1000倍,分成512分,然后求每份对应的数值,形成一个Acos数值查寻表。(很多份的话,肯定不推荐人工一个一个的算,使用python脚本工具来处理等等方法)

结束

核心思想就是把浮点数扩大倍数转化为整数进行运算,确保在不同的平台上面cpu处理的结果是一致的。

我们实现了定点数PEInt与定点向量PEVector3这两个结构体,用来替代我们在Unity中提供的浮点数与Vector向量。整个计算中也涉及到了级数查表以及映射关系如何去处理的相应的变化过程。

好了,我们下次再聊!

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多