Vector3可是说是比较常用的也是最容易出现精度问题的一个。经过测试发现,有一些方法跟原有的Vector3d比起来会有一定的偏差,这些都与float型的精度有关只是多数情况下近似即可。
Vector3d:
/// Vector3d.cs
///
/// The double type version of the Unity struct Vector3.
/// It can solve the problem that the float type may not be accurate enough.
///
/// Unity Vector3结构体的double版实现,以解决float型精度可能不够的问题。
///
/// Created by D子宇 on 2018.3.17
///
/// Email: darkziyu@126.com
using System;
using UnityEngine;
using UnityEngine.Internal;
namespace Mathd
{
public struct Vector3d
{
#region public members
public double x;
public double y;
public double z;
#endregion
#region constructor
public Vector3d(double p_x, double p_y)
{
x = p_x;
y = p_y;
z = 0;
}
public Vector3d(double p_x, double p_y, double p_z)
{
x = p_x;
y = p_y;
z = p_z;
}
#endregion
#region public properties
public double this[int index]
{
get
{
switch (index)
{
case 0:
return x;
case 1:
return y;
case 2:
return z;
default:
throw new IndexOutOfRangeException("Invalid Vector3d index!");
}
}
set
{
switch (index)
{
case 0:
x = value;
break;
case 1:
y = value;
break;
case 2:
z = value;
break;
default:
throw new IndexOutOfRangeException("Invalid Vector3d index!");
}
}
}
public static Vector3d back
{
get
{
return new Vector3d(0, 0, -1);
}
}
public static Vector3d down
{
get
{
return new Vector3d(0, -1, 0);
}
}
public static Vector3d forward
{
get
{
return new Vector3d(0, 0, 1);
}
}
public static Vector3d fwd
{
get
{
return new Vector3d(0, 0, 1);
}
}
public static Vector3d left
{
get
{
return new Vector3d(-1, 0, 0);
}
}
public static Vector3d one
{
get
{
return new Vector3d(1, 1, 1);
}
}
public static Vector3d right
{
get
{
return new Vector3d(1, 0, 0);
}
}
public static Vector3d up
{
get
{
return new Vector3d(0, 1, 0);
}
}
public static Vector3d zero
{
get
{
return new Vector3d(0, 0, 0);
}
}
public double magnitude
{
get
{
return Math.Sqrt(sqrMagnitude);
}
}
public Vector3d normalized
{
get
{
return Normalize(this);
}
}
public double sqrMagnitude
{
get
{
return x * x + y * y + z * z;
}
}
#endregion
#region public functions
/// <summary>
/// 夹角大小
/// </summary>
/// <param name="from"></param>
/// <param name="to"></param>
/// <returns></returns>
public static float Angle(Vector3d from, Vector3d to)
{
double cos = Dot(from.normalized, to.normalized);
if (cos < -1)
{
cos = -1;
}
if (cos > 1)
{
cos = 1;
}
return (float)(Math.Acos(cos) * (180/ Math.PI));
}
/// <summary>
/// 夹角大小(弧度)
/// </summary>
/// <param name="from"></param>
/// <param name="to"></param>
/// <returns></returns>
public static float AngleBetween(Vector3d from, Vector3d to)
{
double cos = Dot(from.normalized, to.normalized);
if (cos < -1)
{
cos = -1;
}
if (cos > 1)
{
cos = 1;
}
return (float)(Math.Acos(cos));
}
/// <summary>
/// 距离限制
/// </summary>
/// <param name="vector"></param>
/// <param name="maxLength"></param>
/// <returns></returns>
public static Vector3d ClampMagnitude(Vector3d vector, double maxLength)
{
if (vector.sqrMagnitude > maxLength * maxLength)
{
return vector.normalized * maxLength;
}
else
{
return vector;
}
}
/// <summary>
/// 差乘
/// </summary>
/// <param name="lhs"></param>
/// <param n