using Island.StandardLib.Storage;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Island.StandardLib.Math
{
public struct Vector3 : IStorable
{
public float x { get; set; }
public float y { get; set; }
public float z { get; set; }
public static Vector3 Zero = new Vector3(0f, 0f, 0f);
public Vector3(float x, float y, float z)
{
this.x = x;
this.y = y;
this.z = z;
}
public static Vector3 Make(float x, float y, float z)
{
return new Vector3(x, y, z);
}
///
/// 使用通信数据初始化
///
/// X:Y:Z
public Vector3(string xyz)
{
string[] l = xyz.Split(':');
if (l.Length == 3)
{
if (float.TryParse(l[0], out float x) &&
float.TryParse(l[1], out float y) &&
float.TryParse(l[2], out float z))
{
this.x = x;
this.y = y;
this.z = z;
}
else
{
this.x = this.y = this.z = 0;
}
}
else x = y = z = 0;
}
public Vector2 GetVectorXZ()
{
return new Vector2(x, z);
}
///
/// 向量加法
///
///
///
public Vector3 ADD(Vector3 vec)
{
return new Vector3(x + vec.x, y + vec.y, z + vec.z);
}
///
/// 向量减法
///
///
///
public Vector3 RED(Vector3 vec)
{
return new Vector3(x - vec.x, y - vec.y, z - vec.z);
}
///
/// 向量数乘
///
///
///
public Vector3 MUL(float vecdx)
{
return new Vector3(vecdx * x, y * vecdx, z * vecdx);
}
///
/// 向量点乘 (内积)
///
///
///
public float DOT(Vector3 vec)
{
return x * vec.x + y * vec.y + z * vec.z;
}
///
/// 向量叉乘 (外积)
///
///
///
public Vector3 FMUL(Vector3 vec)
{
return new Vector3(
y * vec.z - vec.y * z,
-1 * (x * vec.z - vec.x * z),
x * vec.y - vec.x * y);
}
///
/// 如果向量表示点的坐标,计算这个点和指定参数点之间的距离
///
/// 指定点
///
public float DistanceOf(Vector3 vec)
{
float x1 = (float)System.Math.Pow(x - vec.x, 2);
float x2 = (float)System.Math.Pow(y - vec.y, 2);
float x3 = (float)System.Math.Pow(z - vec.z, 2);
return (float)System.Math.Pow(x1 + x2 + x3, 0.5d);
}
///
/// 如果向量表示点的坐标,计算这个点和指定参数点之间的以x, z为平面的距离
///
/// 指定点
///
public float DistanceOf2D(Vector3 vec)
{
float x1 = (float)System.Math.Pow(x - vec.x, 2);
float x3 = (float)System.Math.Pow(z - vec.z, 2);
return (float)System.Math.Pow(x1 + x3, 0.5d);
}
public Vector3 ToCameraRotation()
{
Vector3 vec = new Vector3();
vec.x = x;
vec.z = z;
vec.y = y + 180f;
while (vec.y > 360f)
vec.y -= 360f;
return vec;
}
public static Vector3 Random(float xyzrange)
{
return Random(xyzrange, xyzrange, xyzrange);
}
public static Vector3 Random(float xrange, float yrange, float zrange)
{
Random rd = new Random();
float fx = (float)(rd.NextDouble() - 0.5) * xrange * 2f,
fy = (float)(rd.NextDouble() - 0.5) * yrange * 2f,
fz = (float)(rd.NextDouble() - 0.5) * zrange * 2f;
return new Vector3(fx, fy, fz);
}
public string ToXYZ()
{
return x + ":" + y + ":" + z;
}
public override string ToString()
{
return "(" + x + ", " + y + ", " + z + ")";
}
public bool IsMathNull
{
get
{
return x < 0 || y < 0 || z < 0;
}
}
public override bool Equals(object obj)
{
if (!(obj is Vector3)) return false;
Vector3 d = (Vector3)obj;
return x == d.x && y == d.y && z == d.z;
}
public override int GetHashCode()
{
return x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode();
}
public void WriteToData(DataStorage data)
{
data.Write(x);
data.Write(y);
data.Write(z);
}
public void ReadFromData(DataStorage data)
{
data.Read(out float x);
data.Read(out float y);
data.Read(out float z);
this.x = x;
this.y = y;
this.z = z;
}
public static bool operator ==(Vector3 a, Vector3 b) => a.Equals(b);
public static bool operator !=(Vector3 a, Vector3 b) => !a.Equals(b);
public static Vector3 operator *(Vector3 a, float b) => a.MUL(b);
public static Vector3 operator *(float a, Vector3 b) => b.MUL(a);
public static Vector3 operator +(Vector3 a, Vector3 b) => a.ADD(b);
public static Vector3 operator -(Vector3 a, Vector3 b) => a.RED(b);
}
}