using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; namespace o0Project { public class Variance { List _Value = new List(); int RecordCount; public Variance(int RecordCount = 100) { this.RecordCount = RecordCount; } public void Update(float value) { if (_Value.Count >= RecordCount) _Value.RemoveAt(0); _Value.Add(value); } public float Value { get { float average = 0; foreach (var i in _Value) average += i; average /= _Value.Count; float variance = 0; foreach (var i in _Value) variance += Mathf.Pow(average - i, 2); variance /= _Value.Count; return variance; } } public float StandardDeviation { get { return Mathf.Sqrt(Value); } } } public class Vector3f { public float x; public float y; public float z; public Vector3f() { } public Vector3f(Vector3f v) { x = v[0]; y = v[1]; z = v[2]; } public Vector3f(float[] v) { x = v[0]; y = v[1]; z = v[2]; } public Vector3f(float x = 0, float y = 0, float z = 0) { this.x = x; this.y = y; this.z = z; } public Vector3f assign(Vector3f v) { x = v.x; y = v.y; z = v.z; return this; } public Vector3f assign(float x, float y, float z) { this.x = x; this.y = y; this.z = z; return this; } public float length()//length of vector { return Mathf.Sqrt(x * x + y * y + z * z); } public Vector3f setNormalize() { return assign(this / length()); } public Vector3f setVertical(Vector3f b) { return assign(this[1] * b[2] - this[2] * b[1], this[2] * b[0] - this[0] * b[2], this[0] * b[1] - this[1] * b[0]); } public float angle(Vector3f b) { return Mathf.Asin(Mathf.Sqrt(Mathf.Pow(this[0] - b[0], 2) + Mathf.Pow(this[1] - b[1], 2) + Mathf.Pow(this[2] - b[2], 2)) / 2) * 2; } public Vector3f setRotate(Vector3f shaft, float angle) { float cosAngle = Mathf.Cos(angle); float sinAngle = Mathf.Sin(angle); float rotateDate = (shaft[0] * this[0] + shaft[1] * this[1] + shaft[2] * this[2]) * (1 - cosAngle); Vector3f outerProduct = (new Vector3f(this)).setVertical(shaft); return assign(this[0] * cosAngle + outerProduct[0] * sinAngle + shaft[0] * rotateDate, this[1] * cosAngle + outerProduct[1] * sinAngle + shaft[1] * rotateDate, this[2] * cosAngle + outerProduct[2] * sinAngle + shaft[2] * rotateDate); } public float this[int index] { get { switch (index) { default: case 0: return x; case 1: return y; case 2: return z; } } set { switch (index) { default: case 0: x = value; break; case 1: y = value; break; case 2: z = value; break; } } } public static Vector3f operator +(Vector3f a, Vector3f b) { return new Vector3f(a.x + b.x, a.y + b.y, a.z + b.z); } public static Vector3f operator -(Vector3f a, Vector3f b) { return new Vector3f(a.x - b.x, a.y - b.y, a.z - b.z); } public static Vector3f operator *(Vector3f a, float b) { return new Vector3f(a.x * b, a.y * b, a.z * b); } public static Vector3f operator /(Vector3f a, float b) { return new Vector3f(a.x / b, a.y / b, a.z / b); } } static public class o0 { public static Quaternion FormQuaternion(Vector3 Direction1InIdentity, Vector3 Direction2InIdentity, Vector3 Direction1InQuaternion, Vector3 Direction2InQuaternion,float rate) { var quaIdentity = Quaternion.LookRotation(Direction1InIdentity, Direction2InIdentity); var quaReal = Quaternion.LookRotation(Direction1InQuaternion, Direction2InQuaternion); var quaIdentity2 = Quaternion.LookRotation(Direction2InIdentity, Direction1InIdentity); var quaReal2 = Quaternion.LookRotation(Direction2InQuaternion, Direction1InQuaternion); return Quaternion.Slerp(quaIdentity * Quaternion.Inverse(quaReal), quaIdentity2 * Quaternion.Inverse(quaReal2), rate); } public static Quaternion FormQuaternion(Quaternion original, Vector3 DirectionIdentity, Vector3 Direction1New, float rate) { var global = original * Direction1New; Vector3 DirectionIdentityNormalized = DirectionIdentity.normalized; float angle = Vector3.Angle(global, DirectionIdentityNormalized); //Vector3 gVector = Vector3.RotateTowards(acceleratorGlobal, downVector, angle / 180 * Mathf.PI * Mathf.Pow(overallGVectorCredibility, 1f) * rotationUnCredibility, 1);//偏移量,从陀螺仪数据往加速计数据的偏移量 Vector3 gVector = Vector3.RotateTowards(global, DirectionIdentityNormalized, angle / 180 * Mathf.PI * rate, 1);//偏移量,从陀螺仪数据往加速计数据的偏移量 var newQua = new Quaternion(); newQua.SetFromToRotation(original * Direction1New, gVector); return newQua * original;//一定要反过来乘 } } static public class Extension { public static Quaternion Inverse(this Quaternion qua) { return new Quaternion(-qua.x,-qua.y,-qua.z,qua.w); } public static Quaternion ToQuaternion(this MatrixF2D m) { if(m.Width != 4 || m.Height!=4) throw new Exception("o0 FMatrix m is not 4*4 transfer matrix"); Quaternion q = new Quaternion(); q.w = Mathf.Sqrt(Mathf.Max(0, 1 + m[0, 0] + m[1, 1] + m[2, 2])) / 2; q.x = Mathf.Sqrt(Mathf.Max(0, 1 + m[0, 0] - m[1, 1] - m[2, 2])) / 2; q.y = Mathf.Sqrt(Mathf.Max(0, 1 - m[0, 0] + m[1, 1] - m[2, 2])) / 2; q.z = Mathf.Sqrt(Mathf.Max(0, 1 - m[0, 0] - m[1, 1] + m[2, 2])) / 2; q.x *= Mathf.Sign(q.x * (m[2, 1] - m[1, 2])); q.y *= Mathf.Sign(q.y * (m[0, 2] - m[2, 0])); q.z *= Mathf.Sign(q.z * (m[1, 0] - m[0, 1])); return q; } public static MatrixF2D ToMatrix(Vector3 right, Vector3 up, Vector3 forward, Vector3 position) { var m = MatrixF2D.Identity(4); m.SetColumn(0, new float[] { right.x,right.y,right.z,0}); m.SetColumn(1, new float[] { up.x, up.y, up.z, 0 }); m.SetColumn(2, new float[] { forward.x, forward.y, forward.z, 0 }); m.SetColumn(3, new float[] { position.x, position.y, position.z, 0 }); m[3, 3] = 1; return m; } public static MatrixF2D ToMatrix(Quaternion q) { return ToMatrix(q * Vector3.right, q * Vector3.up, q * Vector3.forward, Vector3.zero); } } public class MatrixF2D { private int _Width; public int Width { get { return _Width; } } public int Height { get { return _Element.Length / Width; } } private float[] _Element; public float[] Element { get { return _Element; } } public float this[int y, int x] { get { x %= Width; if (x < 0) x += Width; y %= Height; if (y < 0) y += Height; return _Element[x + y * Width]; } set{ x %= Width; if (x < 0) x += Width; y %= Height; if (y < 0) y += Height; _Element[x + y * Width] = value; } } public float[] GetRow(int y) { y %= Height; if (y < 0) y += Height; float[] l = new float[Width]; for (var i = 0; i < Width; ++i) l[i] = this[y, i]; return l; } public void SetRow(int y, IEnumerable value) { if (value.Count() != Width) throw new Exception("o0 FMatrix width different"); for (var i = 0; i < Width; ++i) this[y, i] = value.ElementAt(i); } public float[] GetColumn(int x) { x %= Width; if (x < 0) x += Width; float[] l = new float[Height]; for (var i = 0; i < Height; ++i) l[i] = this[i, x]; return l; } public void SetColumn(int x, IEnumerable value) { if (value.Count() != Height) throw new Exception("o0 FMatrix width different"); for (var i = 0; i < Height; ++i) this[i, x] = value.ElementAt(i); } public MatrixF2D(int width = 2, int height = 2) { _Width = width; _Element = new float[width * height]; } public MatrixF2D(int width, float[] element) { _Width = width; _Element = new float[element.Length]; for (var i = 0; i < element.Length; ++i) _Element[i] = element[i]; } public MatrixF2D(MatrixF2D b) { _Width = b.Width; _Element = new float[b.Element.Length]; for (var i = 0; i < _Element.Length; ++i) _Element[i] = b.Element[i]; } public static MatrixF2D operator +(MatrixF2D a, MatrixF2D b) { if (a.Width != b.Width || a.Height != b.Height) throw new Exception("o0 FMatrix size different"); var c = new MatrixF2D(a.Width, a.Height); for (var i = 0; i < a.Element.Length; ++i) c.Element[i] = a.Element[i] + b.Element[i]; return c; } public static MatrixF2D operator -(MatrixF2D a, MatrixF2D b) { if (a.Width != b.Width || a.Height != b.Height) throw new Exception("o0 FMatrix size different"); var c = new MatrixF2D(a.Width, a.Height); for (var i = 0; i < a.Element.Length; ++i) c.Element[i] = a.Element[i] - b.Element[i]; return c; } public static MatrixF2D operator *(MatrixF2D a, MatrixF2D b) { if (a.Width != b.Height) throw new Exception("o0 FMatrix 当矩阵A的列数(column)等于矩阵B的行数(row)时,A与B可以相乘"); var c = new MatrixF2D(b.Width,a.Height); for (var x = 0;x