帧同步定点数运算库 --- 设计与使用文档
版本 : 1.0
目标框架 : .NET Standard 2.0(兼容 Unity 2017.1+)
用途: 帧同步(确定性锁步)游戏逻辑层的定点数学运算
目录
- [帧同步定点数运算库 --- 设计与使用文档](#帧同步定点数运算库 — 设计与使用文档)
- 目录
- [1. 概述](#1. 概述)
- [2. 项目结构](#2. 项目结构)
- [3. 核心类型:FixedInt](#3. 核心类型:FixedInt)
- [3.1 内部表示](#3.1 内部表示)
- [3.2 构造函数](#3.2 构造函数)
- [3.3 类型转换](#3.3 类型转换)
- [3.4 算术运算符](#3.4 算术运算符)
- [3.5 比较运算符](#3.5 比较运算符)
- [3.6 位移运算符](#3.6 位移运算符)
- [3.7 属性](#3.7 属性)
- [3.8 静态常量](#3.8 静态常量)
- [4. 三维向量:FixedVector3](#4. 三维向量:FixedVector3)
- [4.1 构造与分量访问](#4.1 构造与分量访问)
- [4.2 静态方向向量](#4.2 静态方向向量)
- [4.3 向量运算](#4.3 向量运算)
- [4.4 静态工具方法](#4.4 静态工具方法)
- [4.5 Unity 互操作](#4.5 Unity 互操作)
- [5. 角度类型:Args](#5. 角度类型:Args)
- [5.1 设计动机](#5.1 设计动机)
- [5.2 静态常量](#5.2 静态常量)
- [5.3 比较运算](#5.3 比较运算)
- [5.4 格式转换](#5.4 格式转换)
- [6. 数学工具:Calc](#6. 数学工具:Calc)
- [6.1 Abs --- 绝对值](#6.1 Abs — 绝对值)
- [6.2 Sqrt --- 平方根](#6.2 Sqrt — 平方根)
- [6.3 Acos --- 反余弦](#6.3 Acos — 反余弦)
- [6.4 Clamp --- 钳制](#6.4 Clamp — 钳制)
- [7. 查表实现:AcosTable](#7. 查表实现:AcosTable)
- [8. 设计原理与关键决策](#8. 设计原理与关键决策)
- [8.1 缩放因子的选择:1024 (2^10)](#8.1 缩放因子的选择:1024 (2^10))
- [8.2 负数的向零截断](#8.2 负数的向零截断)
- [8.3 类型分离防止单位混淆](#8.3 类型分离防止单位混淆)
- [8.4 查表 vs 实时计算](#8.4 查表 vs 实时计算)
- [8.5 牛顿法的迭代次数](#8.5 牛顿法的迭代次数)
- [9. 使用示例](#9. 使用示例)
- [9.1 基本算数](#9.1 基本算数)
- [9.2 向量运算](#9.2 向量运算)
- [9.3 数学函数](#9.3 数学函数)
- [9.4 Unity 集成(帧同步游戏典型模式)](#9.4 Unity 集成(帧同步游戏典型模式))
- [9.5 网络序列化](#9.5 网络序列化)
- [10. 局限性与扩展方向](#10. 局限性与扩展方向)
- 附录:关键常量速查
1. 概述
本库是一个完全确定性的定点数数学库,专为帧同步(锁步同步)多人游戏设计。
为什么要用定点数? 在帧同步架构中,所有客户端必须独立计算出完全一致的结果。IEEE 754 浮点数在不同 CPU 架构、不同编译器优化级别下,舍入行为可能不同(如 x87 vs SSE 指令集),导致计算结果出现微小偏差,进而破坏帧同步的一致性。定点数以整数为基础进行运算,在所有平台上保证比特级一致。
核心设计特点:
| 特点 | 说明 |
|---|---|
| 整数运算 | 所有运算基于 long(64位有符号整数),跨平台结果一致 |
| 双缩放因子 | 距离量使用 1024 缩放,角度量使用 10000 缩放,防止单位混淆 |
| 查表法三角函数 | arccos 使用 1025 条目的预计算表,O(1) 时间复杂度 + 确定性 |
| 牛顿法开方 | 平方根使用牛顿-拉弗森迭代,可控精度/性能权衡 |
| Unity 互操作 | 条件编译支持与 UnityEngine.Vector3 双向转换 |
| 零分配 | 所有类型均为 struct,不产生 GC 压力 |
2. 项目结构
FixedMath/
├── FixedMath/
│ ├── FixedMath.csproj # 核心库项目 (netstandard2.0)
│ ├── FixedInt.cs # 定点数结构体
│ ├── FixedVector3.cs # 定点数三维向量
│ ├── Args.cs # 角度/三角函数结果包装
│ ├── Calc.cs # 数学工具类 (sqrt, acos, clamp, abs)
│ └── AcosTable.cs # 反余弦预计算查找表 (internal)
└── FixedMathTest/
└── FixedMathTest.cs # 7 个测试用例
类型一览:
| 类型 | 访问级别 | 种类 | 说明 |
|---|---|---|---|
FixedInt |
public struct |
值类型 | 核心定点数 |
FixedVector3 |
public struct |
值类型 | 三维定点向量 |
Args |
public struct |
值类型 | 角度测量结果 |
Calc |
public class |
静态工具类 | 数学函数集合 |
AcosTable |
internal class |
静态数据类 | arccos 查找表(内部实现) |
3. 核心类型:FixedInt
3.1 内部表示
FixedInt 以 long scaledValue 存储数值,真实值 = scaledValue / 1024。
缩放因子:MULTIPLIER_FACTOR = 1024 = 2^10
位移位数:BIT_MOVE_COUNT = 10
真实值 1.0 → scaledValue = 1024
真实值 3.5 → scaledValue = 3584 (3.5 × 1024)
真实值 0.0 → scaledValue = 0
精度 :1 / 1024 ≈ 0.0009765625,约小数点后 3 位有效精度。
范围 :long 型取值范围为 [-2^63, 2^63-1],因此代表真实值的范围为:
最小值 ≈ -9.0 × 10^15
最大值 ≈ +9.0 × 10^15
完全满足游戏场景中的位置、速度、血量等数值需求。
3.2 构造函数
| 构造函数 | 说明 | 精度 |
|---|---|---|
FixedInt(int val) |
整数 → 定点数,scaledValue = val × 1024 |
无损(整数在范围内精确表达) |
FixedInt(float val) |
浮点 → 定点数,scaledValue = Round(val × 1024) |
四舍五入,精度损失 ≤ 0.5/1024 ≈ 0.0005 |
csharp
// 从整数创建(推荐:无精度损失)
FixedInt a = new FixedInt(3); // scaledValue = 3072
// 从浮点创建(仅用于编辑器配置导入等场景)
FixedInt b = new FixedInt(3.5f); // scaledValue = 3584
3.3 类型转换
| 转换 | 方式 | 示例 |
|---|---|---|
int → FixedInt |
隐式(implicit) | FixedInt a = 3; |
float → FixedInt |
显式(explicit) | FixedInt b = (FixedInt)3.5f; |
csharp
// 隐式转换:int → FixedInt,无精度损失
FixedInt health = 100;
// 显式转换:float → FixedInt,需要显式强制转换
FixedInt speed = (FixedInt)5.5f;
// FixedInt → float(仅用于显示层,非确定性)
float displayValue = speed.RawFloat;
// FixedInt → int(截断取整)
int intPart = speed.RawInt;
⚠️ 重要 :
float转换始终伴随精度损失,应在逻辑帧中使用FixedInt之间的运算,仅在表现层 (渲染、UI 显示)才转换为float。
3.4 算术运算符
所有运算符返回新的 FixedInt,不修改原值(不可变语义)。
| 运算符 | 签名 | 底层实现 | 备注 |
|---|---|---|---|
+ |
a + b |
a.SV + b.SV |
直接加缩放值 |
- |
a - b |
a.SV - b.SV |
直接减缩放值 |
* |
a * b |
(a.SV × b.SV) >> 10 |
乘后右移消除多余缩放因子 |
/ |
a / b |
(a.SV << 10) / b.SV |
先左移保留精度再除 |
- (取负) |
-a |
-a.SV |
取反缩放值 |
SV = ScaledValue(内部缩放值)
乘法原理详解:
(a × 1024) × (b × 1024) = (a×b) × 1024^2
结果需要右移 10 位 → (a×b) × 1024 ✓
对于负数,库使用 取反→右移→再取反 的技巧,确保向零截断(而非向负无穷),与 C# 浮点除法行为一致。
除法原理详解:
(a × 1024) << 10 = (a × 1024) × 1024 = a × 1024^2
除以 (b × 1024) → (a/b) × 1024 ✓
先左移再除保留了小数精度,避免整数除法的截断误差。
3.5 比较运算符
所有比较直接对 scaledValue 进行,高效且确定。
csharp
public static bool operator ==(FixedInt a, FixedInt b) // a.SV == b.SV
public static bool operator !=(FixedInt a, FixedInt b) // a.SV != b.SV
public static bool operator > (FixedInt a, FixedInt b) // a.SV > b.SV
public static bool operator < (FixedInt a, FixedInt b) // a.SV < b.SV
public static bool operator >=(FixedInt a, FixedInt b) // a.SV >= b.SV
public static bool operator <=(FixedInt a, FixedInt b) // a.SV <= b.SV
同时覆写了 Equals(object) 和 GetHashCode(),保证相等语义一致。
3.6 位移运算符
| 运算符 | 效果 | 等价于 |
|---|---|---|
a >> n |
算术右移 n 位 | a / (2^n)(向零截断) |
a << n |
左移 n 位 | a × (2^n) |
负数右移使用 取反→移位→再取反 处理,避免 C# 算术右移对负数补符号位(向负无穷截断)导致的逻辑差异。
csharp
FixedInt a = 8; // SV = 8192
FixedInt b = a >> 2; // SV = 2048,真实值 = 2.0
3.7 属性
| 属性 | 类型 | 说明 |
|---|---|---|
ScaledValue |
long (get/set) |
内部缩放值,用于序列化或自定义扩展 |
RawFloat |
float (get) |
近似浮点值 = SV / 1024.0f。仅用于表现层 |
RawInt |
int (get) |
截断取整的整数部分。负数向零截断 |
Abs |
FixedInt (get) |
返回绝对值 |
csharp
FixedInt a = (FixedInt)(-3.5f);
Console.WriteLine(a.ScaledValue); // -3584
Console.WriteLine(a.RawFloat); // -3.5
Console.WriteLine(a.RawInt); // -3 (向零截断)
Console.WriteLine(a.Abs.RawFloat); // 3.5
3.8 静态常量
csharp
public static readonly FixedInt zero = new FixedInt(0); // SV = 0, 真实值 = 0
public static readonly FixedInt one = new FixedInt(1); // SV = 1024, 真实值 = 1
4. 三维向量:FixedVector3
4.1 构造与分量访问
csharp
// 三个定点分量构造
FixedvVector3 position = new FixedVector3(
(FixedInt)10.5f, // x
(FixedInt)0, // y
(FixedInt)(-3.0f) // z
);
// 索引器访问
FixedInt x = position[0]; // 等价于 position.x
FixedInt y = position[1]; // 等价于 position.y
FixedInt z = position[2]; // 等价于 position.z
position[0] = (FixedInt)5; // 修改 x 分量
4.2 静态方向向量
csharp
FixedVector3.zero // ( 0, 0, 0)
FixedVector3.one // ( 1, 1, 1)
FixedVector3.forward // ( 0, 0, 1)
FixedVector3.back // ( 0, 0, -1)
FixedVector3.left // (-1, 0, 0)
FixedVector3.right // ( 1, 0, 0)
FixedVector3.up // ( 0, 1, 0)
FixedVector3.down // ( 0, -1, 0)
4.3 向量运算
| 运算符/属性 | 示例 | 说明 |
|---|---|---|
+ |
v1 + v2 |
分量加法 |
- |
v1 - v2 |
分量减法 |
-v |
-v1 |
取反 |
* |
v * scalar 或 scalar * v |
标量乘法 |
/ |
v / scalar |
标量除法 |
== / != |
v1 == v2 |
全分量比较 |
.sqrMagnitude |
--- | x² + y² + z²(平方长度) |
.magnitude |
--- | Sqrt(x² + y² + z²)(向量长度) |
.normalized |
--- | 单位向量(长度=1),零向量返回 zero |
归一化实现优化:
csharp
// 归一化使用 "乘以倒数" 而非 "三次除法"
// 一次除法算倒数 + 三次乘法,远快于三次除法
FixedInt invMag = FixedInt.one / magnitude;
return new FixedVector3(x * invMag, y * invMag, z * invMag);
4.4 静态工具方法
| 方法 | 签名 | 说明 |
|---|---|---|
SqrMagnitude |
FixedInt SqrMagnitude(FixedVector3 v) |
静态版平方长度 |
Normalize |
FixedVector3 Normalize(FixedVector3 v) |
静态版归一化,返回新向量 |
Normalize() |
void Normalize() |
实例方法,原地归一化(修改自身) |
Dot |
FixedInt Dot(FixedVector3 a, FixedVector3 b) |
点积:ax×bx + ay×by + az×bz |
Cross |
FixedVector3 Cross(FixedVector3 a, FixedVector3 b) |
叉积:a × b |
Angle |
Args Angle(FixedVector3 from, FixedVector3 to) |
两向量夹角,通过 arccos 查表 |
叉积公式(标准右手坐标系):
Cross(a, b) = (
ay×bz - az×by, // x
az×bx - ax×bz, // y
ax×by - ay×bx // z
)
夹角计算流程:
cosθ = Dot(from, to) / (|from| × |to|)
θ = Acos(cosθ) ← 查表 O(1)
若存在零向量(长度为 0),返回 Args.Zero。
4.5 Unity 互操作
通过条件编译 #if UNITY_2017_1_OR_NEWER 提供:
csharp
// Unity → FixedMath(逻辑帧初始化时)
Vector3 unityPos = transform.position;
FixedVector3 logicPos = new FixedVector3(unityPos);
// FixedMath → Unity(表现层同步时)
FixedVector3 logicPos = GetLogicPosition();
Vector3 unityPos = logicPos.ConvertViewVector3();
此外提供 CovertLongArray() 导出为 long[3],用于网络传输或序列化:
csharp
long[] rawData = vector.CovertLongArray();
// rawData = { x.ScaledValue, y.ScaledValue, z.ScaledValue }
5. 角度类型:Args
5.1 设计动机
Args 使用独立的缩放因子 10000 (不同于 FixedInt 的 1024),核心原因是防止距离/位置量与角度量在做乘除运算时意外混淆 。如果你用同一个 FixedInt 类型表示距离和角度,以下代码不会报错:
csharp
FixedInt distance = 5;
FixedInt angle = 3;
FixedInt result = distance * angle; // 编译通过,但逻辑上无意义!
而 Args 使用独立类型 + 独立缩放因子,从类型系统层面杜绝此类错误。
Args.value / multipler = 实际弧度值
例如:PI = 31416 / 10000 = 3.1416 弧度
5.2 静态常量
csharp
Args.Zero = new Args(0, 10000); // 0 弧度 = 0°
Args.HALFPI = new Args(15708, 10000); // π/2 = 1.5708 弧度 = 90°
Args.PI = new Args(31416, 10000); // π = 3.1416 弧度 = 180°
Args.TWOPI = new Args(62832, 10000); // 2π = 6.2832 弧度 = 360°
5.3 比较运算
所有比较运算符(>, <, >=, <=, ==, !=)均要求两个 Args 的 multipler 相同,否则抛出异常。正常情况下不会触发(所有角度都使用 multiplier=10000)。
5.4 格式转换
csharp
Args angle = Calc.Acos(FixedInt.zero); // acos(0) = π/2
// 转为浮点弧度(仅显示层)
float radians = angle.ConvertToFloat(); // ≈ 1.5708f
// 转为整数度数(四舍五入)
int degrees = angle.ConvertViewAngle(); // = 90
6. 数学工具:Calc
6.1 Abs --- 绝对值
csharp
FixedInt result = Calc.Abs(value);
直接在原值的 ScaledValue 上取反。等效于 .Abs 属性,但以静态方法形式提供。
6.2 Sqrt --- 平方根
csharp
FixedInt result = Calc.Sqrt(value, interatorCount = 8);
算法:牛顿-拉弗森迭代法(Newton-Raphson)
初始猜测: x₀ = value
迭代公式: x_{n+1} = (x_n + value / x_n) / 2
终止条件: x_{n+1} == x_n(收敛)或达到最大迭代次数
- 零值直接返回 0
- 负数抛出异常(无实数平方根)
/2用>> 1实现(位运算加速)- 默认最大 8 次迭代,平衡精度与性能
csharp
Calc.Sqrt(25); // → 5
Calc.Sqrt(2); // → ≈ 1.414(SV = 1448)
Calc.Sqrt(0); // → 0
Calc.Sqrt(10000); // → ≈ 100
6.3 Acos --- 反余弦
csharp
Args result = Calc.Acos(FixedInt value);
输入范围 :[-1, 1](自动钳制,越界不抛异常)
算法:查表法(详见第 7 节)
1. 将输入 value ∈ [-1, 1] 线性映射到表索引 [0, 1024]:
input = value × 512 + 512
2. 钳制索引到 [0, 1024]
3. 查表: table[index] → 弧度 × 10000
4. 包装为 Args(value, 10000)
关键映射点:
| 输入 cos 值 | 索引 | 表值 | 实际弧度 |
|---|---|---|---|
| -1.0 | 0 | 31416 | π ≈ 3.1416 |
| -0.5 | 256 | --- | 2π/3 ≈ 2.0944 |
| 0.0 | 512 | 15708 | π/2 ≈ 1.5708 |
| 0.5 | 768 | --- | π/3 ≈ 1.0472 |
| 1.0 | 1024 | 0 | 0 |
6.4 Clamp --- 钳制
csharp
FixedInt result = Calc.Clamp(input, min, max);
csharp
Calc.Clamp(10, 0, 5); // → 5
Calc.Clamp(-2, 0, 5); // → 0
Calc.Clamp(3, 0, 5); // → 3
7. 查表实现:AcosTable
AcosTable 是 internal class,对外不可见。它提供了反余弦的 O(1) 确定性实现。
| 属性 | 值 |
|---|---|
条目数 (IndexCount) |
1024 |
半表条目 (HalfIndexCount) |
512(用于 -1,1→0,1024 映射) |
| 数组长度 | 1025(索引 0~1024) |
缩放因子 (Multipler) |
10000 |
| 内存占用 | 1025 × 4 = 4.1 KB |
| 覆盖范围 | cos ∈ -1.0, 1.0,均匀步长 2.0/1024 ≈ 0.00195 |
预计算方式(在静态构造函数中硬编码):
table[i] = round(acos(-1.0 + i × 2.0/1024) × 10000)
将 1025 个值直接硬编码为 int[] 初始化器,避免运行时触发浮点运算,保证:
- 跨平台一致性:所有平台用同一份硬编码表
- 零初始化开销:数据在程序集加载时即就位
- 无运行时浮点依赖:逻辑帧不执行任何浮点运算
8. 设计原理与关键决策
8.1 缩放因子的选择:1024 (2^10)
选择 2 的幂作为缩放因子,使得乘除法的缩放调整可以用位移实现:
乘法后 descale: >> 10 (比整数除法快)
除数前 upscale: << 10 (比整数乘法快)
10 位精度在游戏中提供约 0.001 的分辨率,对于位置(通常以米/厘米为单位)、速度、血量等足够使用。
8.2 负数的向零截断
C# 中 long 的算术右移(>>)对负数会补 1(向负无穷截断)。例如 -3 >> 1 = -2(期望 -1,向零截断)。
库中对所有涉及负数的右移使用统一模式:
csharp
num = ((num < 0) ? (-(-num >> 10)) : (num >> 10));
// 取反 → 正数右移 → 再取反 = 向零截断
保证了运算结果在各平台上与浮点数学语义一致。
8.3 类型分离防止单位混淆
| 数量类别 | 类型 | 缩放因子 |
|---|---|---|
| 距离、位置、速度 | FixedInt |
1024 |
| 角度(弧度) | Args |
10000 |
两个类型不直接兼容(无隐式/显式转换),防止将角度误用于位置运算。
8.4 查表 vs 实时计算
对于反余弦这类超越函数,实时计算(如泰勒级数、CORDIC)需要多次迭代且难以保证跨平台一致性。查表法用约 4KB 内存换取:
- O(1) 恒定时间复杂度
- 100% 跨平台确定性
- 零运行时浮点计算
8.5 牛顿法的迭代次数
Sqrt 默认 8 次迭代。牛顿法具有二次收敛性,在游戏场景的常见数值范围内,通常 5-6 次即可收敛。8 次是保守上限。
9. 使用示例
9.1 基本算数
csharp
// 创建定点数
FixedInt a = 3; // 隐式从 int
FixedInt b = (FixedInt)2.5f; // 显式从 float
FixedInt c = FixedInt.one; // 静态常量
// 四则运算
FixedInt sum = a + b; // 3 + 2.5 = 5.5
FixedInt diff = a - b; // 3 - 2.5 = 0.5
FixedInt prod = a * b; // 3 × 2.5 = 7.5
FixedInt quot = a / b; // 3 ÷ 2.5 = 1.2
// 比较
if (a > b) { /* ... */ }
if (sum == (FixedInt)5.5f) { /* 注意:浮点转换可能引入误差 */ }
9.2 向量运算
csharp
// 创建向量
FixedVector3 pos = new FixedVector3(0, 0, 0);
FixedVector3 dir = new FixedVector3((FixedInt)1.5f, 0, (FixedInt)2.0f);
// 向量归一化
FixedVector3 unitDir = dir.normalized;
// 移动:位置 = 原位置 + 方向 × 速度 × 时间
FixedInt speed = (FixedInt)5.0f;
FixedInt dt = (FixedInt)(1.0f / 60.0f); // 60 FPS 逻辑帧
FixedVector3 newPos = pos + unitDir * speed * dt;
// 点积判断朝向
FixedInt dotProduct = FixedVector3.Dot(dir, FixedVector3.forward);
bool isFacingForward = dotProduct > FixedInt.zero;
// 夹角
Args angle = FixedVector3.Angle(FixedVector3.forward, dir);
int degrees = angle.ConvertViewAngle(); // 查看多少度
9.3 数学函数
csharp
// 绝对值
FixedInt absVal = Calc.Abs((FixedInt)(-10.5f)); // 10.5
// 平方根(距离计算常用)
FixedInt distance = FixedVector3.SqrMagnitude(from - to);
FixedInt dist = Calc.Sqrt(distance);
// 钳制(血量不低于 0、不超上限)
FixedInt health = Calc.Clamp(currentHealth, FixedInt.zero, maxHealth);
// 反余弦(获取角度)
Args angle = Calc.Acos(FixedInt.one); // acos(1) = 0 弧度
Args angle2 = Calc.Acos(FixedInt.zero); // acos(0) = π/2 弧度
Args angle3 = Calc.Acos((FixedInt)(-1.0f)); // acos(-1) = π 弧度
9.4 Unity 集成(帧同步游戏典型模式)
csharp
// ===== 逻辑层(所有客户端独立执行,结果必须一致)=====
public class LogicBattleSystem
{
FixedVector3 playerPos;
FixedVector3 playerVelocity;
FixedInt moveSpeed = (FixedInt)5.0f;
public void LogicUpdate(FixedInt deltaTime)
{
// 所有运算基于 FixedInt,完全确定
playerPos = playerPos + playerVelocity * deltaTime;
playerVelocity = playerVelocity * (FixedInt)0.98f; // 阻尼
}
}
// ===== 表现层(仅渲染用,不参与逻辑)=====
public class ViewBattleSystem : MonoBehaviour
{
LogicBattleSystem logic;
void Update()
{
// 从逻辑层同步到表现层
Vector3 renderPos = logic.playerPos.ConvertViewVector3();
transform.position = Vector3.Lerp(
transform.position, renderPos, Time.deltaTime * 10f);
}
}
// ===== 初始化:从 Unity 场景导入初始位置 =====
void Start()
{
logic.playerPos = new FixedVector3(transform.position);
}
9.5 网络序列化
csharp
// 发送端:导出原始缩放值
long[] posData = playerPos.CovertLongArray();
SendToNetwork(posData); // { x.ScaledValue, y.ScaledValue, z.ScaledValue }
// 接收端:从缩放值重建
long[] receivedData = ReceiveFromNetwork();
FixedVector3 syncedPos = new FixedVector3(
new FixedInt(receivedData[0]), // 注意:这是 private 构造函数
);
⚠️ 当前
FixedInt(long scaledValue)构造函数是private,外部无法直接以缩放值构造。如需支持序列化反序列化,需要对FixedInt添加public的缩放值构造函数。
10. 局限性与扩展方向
当前局限
| 局限 | 影响 |
|---|---|
无 Vector2 |
2D 游戏需手动模拟或用 FixedVector3(z=0) |
| 无矩阵/四元数 | 旋转只能通过角度+方向向量实现 |
| 无 sin/cos/tan/atan | 仅支持 acos,无法直接计算三角函数 |
无 Lerp/Slerp |
缺乏插值工具,需手动实现 |
| 无随机数生成器 | 缺乏确定性 PRNG,需自行集成 |
FixedInt(long) 私有 |
不便于从缩放值序列化重建 |
无 Floor/Ceil/Round |
缺乏舍入控制 |
无 Max/Min |
仅有 Clamp |
| 除零异常无信息 | 仅抛出空 Exception() |
推荐扩展
高优先级:
├── Vector2(2D 向量)
├── sin / cos 查表实现(可复用 AcosTable 的查表思路)
├── atan / atan2 查表实现
├── FixedInt(long) 改为 public 或提供静态工厂方法
├── 确定性随机数(LCRNG 或 Xorshift)
└── Lerp / MoveTowards
中优先级:
├── Matrix4x4 / 旋转矩阵
├── Quaternion(定点四元数)
├── Floor / Ceil / Round / Max / Min
├── 除零异常携带有意义消息
└── 单元测试项目(当前测试较简单)
低优先级:
├── BoundingBox / AABB
├── Ray / RaycastHit
├── Plane
└── 性能测试基准项目
附录:关键常量速查
| 常量 | 值 | 说明 |
|---|---|---|
MULTIPLIER_FACTOR |
1024 | FixedInt 缩放因子 |
BIT_MOVE_COUNT |
10 | FixedInt 位移位数 |
AcosTable.IndexCount |
1024 | 查表条目数 |
AcosTable.Multipler |
10000 | 角度缩放因子 |
Args.PI.value |
31416 | π × 10000 |
Args.HALFPI.value |
15708 | π/2 × 10000 |
Args.TWOPI.value |
62832 | 2π × 10000 |
本文档覆盖
FixedInt、FixedVector3、Args、Calc、AcosTable全部公开 API 与内部实现细节。如需了解最新的代码变更,请查看 Git 提交记录。