[英]Is there a way to compress Y rotation axis to one byte?
我正在制作一個 Unity 多人游戲,我想將 Y 旋轉軸從發送整個四元數壓縮到只發送一個字節。
我的問題是,是否有可能以更...正確的方式進行第三次壓縮嘗試,或者我的潛在解決方案是我能實現的唯一可能的事情?
我不會聲稱您總共節省了 15 個字節^^
如果無論如何您只需要一個旋轉組件,那么同步單個浮點數(4 個字節)的第一步實際上非常明顯;)
我還要說,超越這聽起來有點像不必要的微優化。
增量同步非常聰明,乍一看是從 4 字節到 2 字節的 100% 改進。
但
它也很容易出錯,如果只有一次傳輸失敗,go 可能會不同步。
這當然會將精度降低到 1 度 integer 步長而不是全float
值。
老實說,為了穩定性和精確性,我會堅持使用 4 個字節。
使用 2 個字節,您實際上可以 go 比您的嘗試更好!
為什么僅僅為了值的符號而浪費整個字節?
使用short
你只需要 map 你的浮點范圍-180
到180
到范圍-32768
到32767
。
發送
// your delta between -180 and 180
float actualAngleDelta;
var shortAngleDelta = (short)Mathf.RondToInt(actualAngleDelta / 180f * shortMaxValue);
var sendBytes = BitConverter.GetBytes(shortAngleDelta);
接收
short shortAngleDelta = BitConverter.ToInt16(receivedBytes);
float actualAngleDelta = (float) shortAngleDelta / (float)short.MaxValue * 360f;
但老實說,您不應該同步增量,而是同步實際值。
所以,使用ushort
!
它涵蓋了從0
到65535
的值,因此僅 map 可能是 360 度。 當然,您會在精度上有所損失,但不會下降到全度;)
// A value between 0 and 360
float actualAngle;
ushort ushortAngle = (ushort) Mathf.RoundToInt((actualAngle % 360f) / 360f * ushort.MaxValue);
byte[] sendBytes = BitConverter.GetBytes(ushortAngle);
接收
ushort ushortAngle = BitConverter.ToUInt16(receivedBytes, 0);
float actualAngle = (float)ushortAngle / (float)ushort.MaxValue * 360f;
兩者都將精度保持在大約0.0055
(= 360/65535) 度!
如果您無論如何都可以選擇較低的精度,那么您可以選擇 go 並說您不會以度數同步每個精確的旋轉角度,而是將圓除以 360 而不是 256 步。
然后你可以 map 增量到你的較小粒度的“度”角,並且可以在一個字節中覆蓋整個圓:
發送
byte sendByte = (byte)Mathf.RoundToInt((actualAngle % 360f) / 360f * (float)byte.MaxValue);
接收
float actualAngle = receivedByte / (float)byte.MaxValue * 360f;
其精度約為1.4
度。
但老實說,所有這些來回計算真的值得節省 2/3 字節嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.