Compare commits

..

No commits in common. "2c498a6dd9089cff5c20ef172de3136ba2354c8e" and "c7bce31f34da99b68c709cef496eacfe099fc49f" have entirely different histories.

16 changed files with 614 additions and 821 deletions

View File

@ -1,6 +0,0 @@
DoxyGen/DoxyWarnLogfile.txt
.vscode/settings.json
**bin
**obj
**.meta
*.sln

View File

@ -1,13 +1,11 @@
using System; using System;
namespace LinearAlgebra namespace Passer.LinearAlgebra {
{
/// <summary> /// <summary>
/// %Angle utilities /// %Angle utilities
/// </summary> /// </summary>
public static class Angle public static class Angle {
{
public const float pi = 3.1415927410125732421875F; public const float pi = 3.1415927410125732421875F;
// public static float Rad2Deg = 360.0f / ((float)Math.PI * 2); // public static float Rad2Deg = 360.0f / ((float)Math.PI * 2);
// public static float Deg2Rad = ((float)Math.PI * 2) / 360.0f; // public static float Deg2Rad = ((float)Math.PI * 2) / 360.0f;
@ -23,8 +21,7 @@ namespace LinearAlgebra
/// <param name="max">The maximum angle</param> /// <param name="max">The maximum angle</param>
/// <returns>The clamped angle</returns> /// <returns>The clamped angle</returns>
/// Angles are normalized /// Angles are normalized
public static float Clamp(float angle, float min, float max) public static float Clamp(float angle, float min, float max) {
{
float normalizedAngle = Normalize(angle); float normalizedAngle = Normalize(angle);
return Float.Clamp(normalizedAngle, min, max); return Float.Clamp(normalizedAngle, min, max);
} }
@ -36,8 +33,7 @@ namespace LinearAlgebra
/// <param name="b">The second angle</param> /// <param name="b">The second angle</param>
/// <returns>the angle between the two angles</returns> /// <returns>the angle between the two angles</returns>
/// Angle values should be degrees /// Angle values should be degrees
public static float Difference(float a, float b) public static float Difference(float a, float b) {
{
float r = Normalize(b - a); float r = Normalize(b - a);
return r; return r;
} }
@ -48,8 +44,7 @@ namespace LinearAlgebra
/// <param name="angle">The angle to normalize</param> /// <param name="angle">The angle to normalize</param>
/// <returns>The normalized angle in interval (-180..180] </returns> /// <returns>The normalized angle in interval (-180..180] </returns>
/// Angle values should be in degrees /// Angle values should be in degrees
public static float Normalize(float angle) public static float Normalize(float angle) {
{
if (float.IsInfinity(angle)) if (float.IsInfinity(angle))
return angle; return angle;
@ -66,8 +61,7 @@ namespace LinearAlgebra
/// <param name="maxAngle">Maximum angle to rotate</param> /// <param name="maxAngle">Maximum angle to rotate</param>
/// <returns>The resulting angle</returns> /// <returns>The resulting angle</returns>
/// This function is compatible with radian and degrees angles /// This function is compatible with radian and degrees angles
public static float MoveTowards(float fromAngle, float toAngle, float maxAngle) public static float MoveTowards(float fromAngle, float toAngle, float maxAngle) {
{
float d = toAngle - fromAngle; float d = toAngle - fromAngle;
d = Normalize(d); d = Normalize(d);
d = Math.Sign(d) * Float.Clamp(Math.Abs(d), 0, maxAngle); d = Math.Sign(d) * Float.Clamp(Math.Abs(d), 0, maxAngle);
@ -83,8 +77,7 @@ namespace LinearAlgebra
/// Vectors a and b must be normalized /// Vectors a and b must be normalized
/// \deprecated Please use Vector2.ToFactor instead. /// \deprecated Please use Vector2.ToFactor instead.
[Obsolete("Please use Vector2.ToFactor instead.")] [Obsolete("Please use Vector2.ToFactor instead.")]
public static float ToFactor(Vector2 v1, Vector2 v2) public static float ToFactor(Vector2 v1, Vector2 v2) {
{
return (1 - Vector2.Dot(v1, v2)) / 2; return (1 - Vector2.Dot(v1, v2)) / 2;
} }

View File

@ -1,18 +1,14 @@
namespace LinearAlgebra namespace Passer.LinearAlgebra {
{
public class Direction public class Direction {
{
public float horizontal; public float horizontal;
public float vertical; public float vertical;
public Direction() public Direction() {
{
horizontal = 0; horizontal = 0;
vertical = 0; vertical = 0;
} }
public Direction(float horizontal, float vertical) public Direction(float horizontal, float vertical) {
{
this.horizontal = horizontal; this.horizontal = horizontal;
this.vertical = vertical; this.vertical = vertical;
//Normalize(); //Normalize();
@ -25,10 +21,8 @@ namespace LinearAlgebra
public readonly static Direction left = new Direction(-90, 0); public readonly static Direction left = new Direction(-90, 0);
public readonly static Direction right = new Direction(90, 0); public readonly static Direction right = new Direction(90, 0);
public void Normalize() public void Normalize() {
{ if (this.vertical > 90 || this.vertical < -90) {
if (this.vertical > 90 || this.vertical < -90)
{
this.horizontal += 180; this.horizontal += 180;
this.vertical = 180 - this.vertical; this.vertical = 180 - this.vertical;
} }

View File

@ -1,11 +1,9 @@
namespace LinearAlgebra namespace Passer.LinearAlgebra {
{
/// <summary> /// <summary>
/// Float number utilities /// Float number utilities
/// </summary> /// </summary>
public class Float public class Float {
{
/// <summary> /// <summary>
/// The precision of float numbers /// The precision of float numbers
/// </summary> /// </summary>
@ -22,8 +20,7 @@ namespace LinearAlgebra
/// <param name="min">The minimum value</param> /// <param name="min">The minimum value</param>
/// <param name="max">The maximum value</param> /// <param name="max">The maximum value</param>
/// <returns>The clamped value</returns> /// <returns>The clamped value</returns>
public static float Clamp(float f, float min, float max) public static float Clamp(float f, float min, float max) {
{
if (f < min) if (f < min)
return min; return min;
if (f > max) if (f > max)
@ -36,8 +33,7 @@ namespace LinearAlgebra
/// </summary> /// </summary>
/// <param name="f">The value to clamp</param> /// <param name="f">The value to clamp</param>
/// <returns>The clamped value</returns> /// <returns>The clamped value</returns>
public static float Clamp01(float f) public static float Clamp01(float f) {
{
return Clamp(f, 0, 1); return Clamp(f, 0, 1);
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
using System; using System;
namespace LinearAlgebra namespace Passer.LinearAlgebra
{ {
public class Quat32 public class Quat32
{ {

View File

@ -2,19 +2,15 @@ using System;
#if UNITY_5_3_OR_NEWER #if UNITY_5_3_OR_NEWER
using Quaternion = UnityEngine.Quaternion; using Quaternion = UnityEngine.Quaternion;
#endif #endif
namespace Passer.LinearAlgebra {
namespace LinearAlgebra public class QuaternionOf<T> {
{
public class QuaternionOf<T>
{
public T x; public T x;
public T y; public T y;
public T z; public T z;
public T w; public T w;
public QuaternionOf(T x, T y, T z, T w) public QuaternionOf(T x, T y, T z, T w) {
{
this.x = x; this.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;

View File

@ -3,42 +3,35 @@ using System;
using Vector3Float = UnityEngine.Vector3; using Vector3Float = UnityEngine.Vector3;
#endif #endif
namespace LinearAlgebra namespace Passer.LinearAlgebra {
{ public class Spherical {
public class Spherical
{
public float distance; public float distance;
public Direction direction; public Direction direction;
public static Spherical zero = new Spherical(0, 0, 0); public static Spherical zero = new Spherical(0, 0, 0);
public static Spherical forward = new Spherical(1, 0, 0); public static Spherical forward = new Spherical(1, 0, 0);
public Spherical(float distance, float horizontal, float vertical) public Spherical(float distance, float horizontal, float vertical) {
{
this.distance = distance; this.distance = distance;
this.direction = new Direction(horizontal, vertical); this.direction = new Direction(horizontal, vertical);
} }
public Spherical(float distance, Direction direction) public Spherical(float distance, Direction direction) {
{
this.distance = distance; this.distance = distance;
this.direction = direction; this.direction = direction;
} }
public static Spherical FromVector3(Vector3Float v) public static Spherical FromVector3(Vector3Float v) {
{
float distance = v.magnitude; float distance = v.magnitude;
if (distance == 0.0f) if (distance == 0.0f)
return new Spherical(distance, 0, 0); return new Spherical(distance, 0, 0);
else else {
{
float verticalAngle = (float)((Angle.pi / 2 - Math.Acos(v.y / distance)) * Angle.Rad2Deg); float verticalAngle = (float)((Angle.pi / 2 - Math.Acos(v.y / distance)) * Angle.Rad2Deg);
float horizontalAngle = (float)Math.Atan2(v.x, v.z) * Angle.Rad2Deg; float horizontalAngle = (float) Math.Atan2(v.x, v.z) * Angle.Rad2Deg;
return new Spherical(distance, horizontalAngle, verticalAngle); return new Spherical(distance, horizontalAngle, verticalAngle);
} }
} }
public Vector3Float ToVector3() public Vector3Float ToVector3() {
{
float verticalRad = (Angle.pi / 2) - this.direction.vertical * Angle.Deg2Rad; float verticalRad = (Angle.pi / 2) - this.direction.vertical * Angle.Deg2Rad;
float horizontalRad = this.direction.horizontal * Angle.Deg2Rad; float horizontalRad = this.direction.horizontal * Angle.Deg2Rad;
float cosVertical = (float)Math.Cos(verticalRad); float cosVertical = (float)Math.Cos(verticalRad);

View File

@ -1,4 +1,4 @@
namespace LinearAlgebra namespace Passer.LinearAlgebra
{ {
public class SwingTwist public class SwingTwist

View File

@ -1,63 +1,50 @@
using System; using System;
using System.Numerics; using System.Numerics;
namespace LinearAlgebra namespace Passer.LinearAlgebra {
{
public class Vector2Of<T> where T : IComparable<T> public class Vector2Of<T> where T : IComparable<T> {
{
public T x; public T x;
public T y; public T y;
public Vector2Of(T x, T y) public Vector2Of(T x, T y) {
{
this.x = x; this.x = x;
this.y = y; this.y = y;
} }
} }
public class Vector2Int : Vector2Of<int> public class Vector2Int : Vector2Of<int> {
{
public Vector2Int(int x, int y) : base(x, y) { } public Vector2Int(int x, int y) : base(x, y) { }
public static Vector2Int operator -(Vector2Int v1, Vector2Int v2) public static Vector2Int operator -(Vector2Int v1, Vector2Int v2) {
{
return new Vector2Int(v1.x - v2.x, v1.y - v2.y); return new Vector2Int(v1.x - v2.x, v1.y - v2.y);
} }
public float magnitude public float magnitude {
{ get {
get
{
return (float)Math.Sqrt(this.x * this.x + this.y * this.y); return (float)Math.Sqrt(this.x * this.x + this.y * this.y);
} }
} }
public static float Distance(Vector2Int v1, Vector2Int v2) public static float Distance(Vector2Int v1, Vector2Int v2) {
{
return (v1 - v2).magnitude; return (v1 - v2).magnitude;
} }
} }
public class Vector2Float : Vector2Of<float> public class Vector2Float : Vector2Of<float> {
{
public Vector2Float(float x, float y) : base(x, y) { } public Vector2Float(float x, float y) : base(x, y) { }
public static Vector2Float operator -(Vector2Float v1, Vector2Float v2) public static Vector2Float operator -(Vector2Float v1, Vector2Float v2) {
{
return new Vector2Float(v1.x - v2.x, v1.y - v2.y); return new Vector2Float(v1.x - v2.x, v1.y - v2.y);
} }
public float magnitude public float magnitude {
{ get {
get
{
return (float)Math.Sqrt(this.x * this.x + this.y * this.y); return (float)Math.Sqrt(this.x * this.x + this.y * this.y);
} }
} }
public static float Distance(Vector2Float v1, Vector2Float v2) public static float Distance(Vector2Float v1, Vector2Float v2) {
{
return (v1 - v2).magnitude; return (v1 - v2).magnitude;
} }
} }
@ -65,8 +52,7 @@ namespace LinearAlgebra
/// <summary> /// <summary>
/// 2-dimensional vectors /// 2-dimensional vectors
/// </summary> /// </summary>
public struct Vector2 : IEquatable<Vector2> public struct Vector2 : IEquatable<Vector2> {
{
/// <summary> /// <summary>
/// The right axis of the vector /// The right axis of the vector
@ -83,8 +69,7 @@ namespace LinearAlgebra
/// </summary> /// </summary>
/// <param name="x">x axis value</param> /// <param name="x">x axis value</param>
/// <param name="y">y axis value</param> /// <param name="y">y axis value</param>
public Vector2(float x, float y) public Vector2(float x, float y) {
{
this.x = x; this.x = x;
this.y = y; this.y = y;
} }
@ -129,10 +114,8 @@ namespace LinearAlgebra
/// The squared length is computationally simpler than the real length. /// The squared length is computationally simpler than the real length.
/// Think of Pythagoras A^2 + B^2 = C^2. /// Think of Pythagoras A^2 + B^2 = C^2.
/// This leaves out the calculation of the squared root of C. /// This leaves out the calculation of the squared root of C.
public float sqrMagnitude public float sqrMagnitude {
{ get {
get
{
float d = x * x + y * y; float d = x * x + y * y;
return d; return d;
} }
@ -142,10 +125,8 @@ namespace LinearAlgebra
/// The length of this vector /// The length of this vector
/// </summary> /// </summary>
/// <returns>The length of this vector</returns> /// <returns>The length of this vector</returns>
public float magnitude public float magnitude {
{ get {
get
{
float d = (float)Math.Sqrt(x * x + y * y); float d = (float)Math.Sqrt(x * x + y * y);
return d; return d;
} }
@ -155,10 +136,8 @@ namespace LinearAlgebra
/// Convert the vector to a length of a 1 /// Convert the vector to a length of a 1
/// </summary> /// </summary>
/// <returns>The vector with length 1</returns> /// <returns>The vector with length 1</returns>
public Vector2 normalized public Vector2 normalized {
{ get {
get
{
float l = magnitude; float l = magnitude;
Vector2 v = zero; Vector2 v = zero;
if (l > Float.epsilon) if (l > Float.epsilon)
@ -173,8 +152,7 @@ namespace LinearAlgebra
/// <param name="v1">The first vector</param> /// <param name="v1">The first vector</param>
/// <param name="v2">The second vector</param> /// <param name="v2">The second vector</param>
/// <returns>The result of adding the two vectors</returns> /// <returns>The result of adding the two vectors</returns>
public static Vector2 operator +(Vector2 v1, Vector2 v2) public static Vector2 operator +(Vector2 v1, Vector2 v2) {
{
Vector2 v = new Vector2(v1.x + v2.x, v1.y + v2.y); Vector2 v = new Vector2(v1.x + v2.x, v1.y + v2.y);
return v; return v;
} }
@ -185,8 +163,7 @@ namespace LinearAlgebra
/// <param name="v1">The first vector</param> /// <param name="v1">The first vector</param>
/// <param name="v2">The second vector</param> /// <param name="v2">The second vector</param>
/// <returns>The result of adding the two vectors</returns> /// <returns>The result of adding the two vectors</returns>
public static Vector2 operator -(Vector2 v1, Vector2 v2) public static Vector2 operator -(Vector2 v1, Vector2 v2) {
{
Vector2 v = new Vector2(v1.x - v2.x, v1.y - v2.y); Vector2 v = new Vector2(v1.x - v2.x, v1.y - v2.y);
return v; return v;
} }
@ -197,8 +174,7 @@ namespace LinearAlgebra
/// <param name="v1">The vector to negate</param> /// <param name="v1">The vector to negate</param>
/// <returns>The negated vector</returns> /// <returns>The negated vector</returns>
/// This will result in a vector pointing in the opposite direction /// This will result in a vector pointing in the opposite direction
public static Vector2 operator -(Vector2 v1) public static Vector2 operator -(Vector2 v1) {
{
Vector2 v = new Vector2(-v1.x, -v1.y); Vector2 v = new Vector2(-v1.x, -v1.y);
return v; return v;
} }
@ -210,8 +186,7 @@ namespace LinearAlgebra
/// <param name="f">The scaling factor</param> /// <param name="f">The scaling factor</param>
/// <returns>The scaled vector</returns> /// <returns>The scaled vector</returns>
/// Each component of the vector will be multipled with the same factor. /// Each component of the vector will be multipled with the same factor.
public static Vector2 operator *(Vector2 v1, float f) public static Vector2 operator *(Vector2 v1, float f) {
{
Vector2 v = new Vector2(v1.x * f, v1.y * f); Vector2 v = new Vector2(v1.x * f, v1.y * f);
return v; return v;
} }
@ -223,8 +198,7 @@ namespace LinearAlgebra
/// <param name="v1">The vector to scale</param> /// <param name="v1">The vector to scale</param>
/// <returns>The scaled vector</returns> /// <returns>The scaled vector</returns>
/// Each component of the vector will be multipled with the same factor. /// Each component of the vector will be multipled with the same factor.
public static Vector2 operator *(float f, Vector2 v1) public static Vector2 operator *(float f, Vector2 v1) {
{
Vector2 v = new Vector2(f * v1.x, f * v1.y); Vector2 v = new Vector2(f * v1.x, f * v1.y);
return v; return v;
} }
@ -236,8 +210,7 @@ namespace LinearAlgebra
/// <param name="f">The scaling factor</param> /// <param name="f">The scaling factor</param>
/// <returns>The scaled vector</returns> /// <returns>The scaled vector</returns>
/// Each component of the vector will be devided by the same factor. /// Each component of the vector will be devided by the same factor.
public static Vector2 operator /(Vector2 v1, float f) public static Vector2 operator /(Vector2 v1, float f) {
{
Vector2 v = new Vector2(v1.x / f, v1.y / f); Vector2 v = new Vector2(v1.x / f, v1.y / f);
return v; return v;
} }
@ -254,8 +227,7 @@ namespace LinearAlgebra
/// </summary> /// </summary>
/// <param name="obj">The object to compare to</param> /// <param name="obj">The object to compare to</param>
/// <returns><em>false</em> when the object is not a Vector2 or does not have equal values</returns> /// <returns><em>false</em> when the object is not a Vector2 or does not have equal values</returns>
public override bool Equals(object obj) public override bool Equals(object obj) {
{
if (!(obj is Vector2 v)) if (!(obj is Vector2 v))
return false; return false;
@ -271,8 +243,7 @@ namespace LinearAlgebra
/// Note that this uses a Float equality check which cannot be not exact in all cases. /// Note that this uses a Float equality check which cannot be not exact in all cases.
/// In most cases it is better to check if the Vector2.Distance between the vectors is smaller than Float.epsilon /// In most cases it is better to check if the Vector2.Distance between the vectors is smaller than Float.epsilon
/// Or more efficient: (v1 - v2).sqrMagnitude < Float.sqrEpsilon /// Or more efficient: (v1 - v2).sqrMagnitude < Float.sqrEpsilon
public static bool operator ==(Vector2 v1, Vector2 v2) public static bool operator ==(Vector2 v1, Vector2 v2) {
{
return (v1.x == v2.x && v1.y == v2.y); return (v1.x == v2.x && v1.y == v2.y);
} }
@ -285,8 +256,7 @@ namespace LinearAlgebra
/// Note that this uses a Float equality check which cannot be not exact in all case. /// Note that this uses a Float equality check which cannot be not exact in all case.
/// In most cases it is better to check if the Vector2.Distance between the vectors is smaller than Float.epsilon. /// In most cases it is better to check if the Vector2.Distance between the vectors is smaller than Float.epsilon.
/// Or more efficient: (v1 - v2).sqrMagnitude < Float.sqrEpsilon /// Or more efficient: (v1 - v2).sqrMagnitude < Float.sqrEpsilon
public static bool operator !=(Vector2 v1, Vector2 v2) public static bool operator !=(Vector2 v1, Vector2 v2) {
{
return (v1.x != v2.x || v1.y != v2.y); return (v1.x != v2.x || v1.y != v2.y);
} }
@ -294,8 +264,7 @@ namespace LinearAlgebra
/// Get an hash code for the vector /// Get an hash code for the vector
/// </summary> /// </summary>
/// <returns>The hash code</returns> /// <returns>The hash code</returns>
public override int GetHashCode() public override int GetHashCode() {
{
return (x, y).GetHashCode(); return (x, y).GetHashCode();
} }
@ -305,8 +274,7 @@ namespace LinearAlgebra
/// <param name="v1">The first vector</param> /// <param name="v1">The first vector</param>
/// <param name="v2">The second vector</param> /// <param name="v2">The second vector</param>
/// <returns>The distance between the two vectors</returns> /// <returns>The distance between the two vectors</returns>
public static float Distance(Vector2 v1, Vector2 v2) public static float Distance(Vector2 v1, Vector2 v2) {
{
float x = v1.x - v2.x; float x = v1.x - v2.x;
float y = v1.y - v2.y; float y = v1.y - v2.y;
float d = (float)Math.Sqrt(x * x + y * y); float d = (float)Math.Sqrt(x * x + y * y);
@ -319,8 +287,7 @@ namespace LinearAlgebra
/// <param name="v1">The first vector</param> /// <param name="v1">The first vector</param>
/// <param name="v2">The second vector</param> /// <param name="v2">The second vector</param>
/// <returns>The dot product of the two vectors</returns> /// <returns>The dot product of the two vectors</returns>
public static float Dot(Vector2 v1, Vector2 v2) public static float Dot(Vector2 v1, Vector2 v2) {
{
return v1.x * v2.x + v1.y * v2.y; return v1.x * v2.x + v1.y * v2.y;
} }
@ -334,8 +301,7 @@ namespace LinearAlgebra
/// The factor f is unclamped. Value 0 matches the *v1* vector, Value 1 /// The factor f is unclamped. Value 0 matches the *v1* vector, Value 1
/// matches the *v2* vector Value -1 is *v1* vector minus the difference /// matches the *v2* vector Value -1 is *v1* vector minus the difference
/// between *v1* and *v2* etc. /// between *v1* and *v2* etc.
public static Vector2 Lerp(Vector2 v1, Vector2 v2, float f) public static Vector2 Lerp(Vector2 v1, Vector2 v2, float f) {
{
Vector2 v = v1 + (v2 - v1) * f; Vector2 v = v1 + (v2 - v1) * f;
return v; return v;
} }
@ -347,8 +313,7 @@ namespace LinearAlgebra
/// <param name="to">The ending vector</param> /// <param name="to">The ending vector</param>
/// <param name="axis">The axis to rotate around</param> /// <param name="axis">The axis to rotate around</param>
/// <returns>The signed angle in degrees</returns> /// <returns>The signed angle in degrees</returns>
public static float SignedAngle(Vector2 from, Vector2 to) public static float SignedAngle(Vector2 from, Vector2 to) {
{
//float sign = Math.Sign(v1.y * v2.x - v1.x * v2.y); //float sign = Math.Sign(v1.y * v2.x - v1.x * v2.y);
//return Vector2.Angle(v1, v2) * sign; //return Vector2.Angle(v1, v2) * sign;
@ -371,15 +336,13 @@ namespace LinearAlgebra
/// <param name="v1">The vector to rotate</param> /// <param name="v1">The vector to rotate</param>
/// <param name="angle">The angle in degrees</param> /// <param name="angle">The angle in degrees</param>
/// <returns></returns> /// <returns></returns>
public static Vector2 Rotate(Vector2 v1, float angle) public static Vector2 Rotate(Vector2 v1, float angle) {
{
float sin = (float)Math.Sin(angle * Angle.Deg2Rad); float sin = (float)Math.Sin(angle * Angle.Deg2Rad);
float cos = (float)Math.Cos(angle * Angle.Deg2Rad); float cos = (float)Math.Cos(angle * Angle.Deg2Rad);
float tx = v1.x; float tx = v1.x;
float ty = v1.y; float ty = v1.y;
Vector2 v = new Vector2() Vector2 v = new Vector2() {
{
x = (cos * tx) - (sin * ty), x = (cos * tx) - (sin * ty),
y = (sin * tx) + (cos * ty) y = (sin * tx) + (cos * ty)
}; };
@ -393,8 +356,7 @@ namespace LinearAlgebra
/// <param name="v2">The second vector</param> /// <param name="v2">The second vector</param>
/// <returns>The resulting factor in interval [0..1]</returns> /// <returns>The resulting factor in interval [0..1]</returns>
/// Vectors a and b must be normalized /// Vectors a and b must be normalized
public static float ToFactor(Vector2 v1, Vector2 v2) public static float ToFactor(Vector2 v1, Vector2 v2) {
{
return (1 - Vector2.Dot(v1, v2)) / 2; return (1 - Vector2.Dot(v1, v2)) / 2;
} }
} }

View File

@ -1,16 +1,13 @@
#if !UNITY_5_3_OR_NEWER #if !UNITY_5_3_OR_NEWER
using System; using System;
namespace LinearAlgebra namespace Passer.LinearAlgebra {
{ public class Vector3Of<T> {
public class Vector3Of<T>
{
public T x; public T x;
public T y; public T y;
public T z; public T z;
public Vector3Of(T x, T y, T z) public Vector3Of(T x, T y, T z) {
{
this.x = x; this.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
@ -21,16 +18,13 @@ namespace LinearAlgebra
// } // }
} }
public class Vector3Int : Vector3Of<int> public class Vector3Int : Vector3Of<int> {
{
public Vector3Int(int x, int y, int z) : base(x, y, z) { } public Vector3Int(int x, int y, int z) : base(x, y, z) { }
} }
public class Vector3Float : Vector3Of<float> public class Vector3Float : Vector3Of<float> {
{
public Vector3Float(float x, float y, float z) : base(x, y, z) { } public Vector3Float(float x, float y, float z) : base(x, y, z) { }
public float magnitude public float magnitude {
{
get => (float)Math.Sqrt(this.x * this.x + this.y * this.y + this.z * this.z); get => (float)Math.Sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
} }
} }
@ -39,8 +33,7 @@ namespace LinearAlgebra
/// 3-dimensional vectors /// 3-dimensional vectors
/// </summary> /// </summary>
/// This uses the right-handed coordinate system. /// This uses the right-handed coordinate system.
public struct Vector3 : IEquatable<Vector3> public struct Vector3 : IEquatable<Vector3> {
{
/// <summary> /// <summary>
/// The right axis of the vector /// The right axis of the vector
@ -61,8 +54,7 @@ namespace LinearAlgebra
/// <param name="x">x axis value</param> /// <param name="x">x axis value</param>
/// <param name="y">y axis value</param> /// <param name="y">y axis value</param>
/// <param name="z">z axis value</param> /// <param name="z">z axis value</param>
public Vector3(float x, float y, float z) public Vector3(float x, float y, float z) {
{
this.x = x; this.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
@ -101,19 +93,15 @@ namespace LinearAlgebra
/// </summary> /// </summary>
public static readonly Vector3 forward = new Vector3(0, 1, 0); public static readonly Vector3 forward = new Vector3(0, 1, 0);
public float magnitude public float magnitude {
{ get {
get
{
float d = (float)Math.Sqrt(x * x + y * y); float d = (float)Math.Sqrt(x * x + y * y);
return d; return d;
} }
} }
public Vector3 normalized public Vector3 normalized {
{ get {
get
{
float l = magnitude; float l = magnitude;
Vector3 v = zero; Vector3 v = zero;
if (l > Float.epsilon) if (l > Float.epsilon)
@ -122,79 +110,66 @@ namespace LinearAlgebra
} }
} }
public static Vector3 operator +(Vector3 v1, Vector3 v2) public static Vector3 operator +(Vector3 v1, Vector3 v2) {
{
Vector3 v = new Vector3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z); Vector3 v = new Vector3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
return v; return v;
} }
public static Vector3 operator -(Vector3 v1, Vector3 v2) public static Vector3 operator -(Vector3 v1, Vector3 v2) {
{
Vector3 v = new Vector3(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z); Vector3 v = new Vector3(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
return v; return v;
} }
public static Vector3 operator -(Vector3 v1) public static Vector3 operator -(Vector3 v1) {
{
Vector3 v = new Vector3(-v1.x, -v1.y, -v1.z); Vector3 v = new Vector3(-v1.x, -v1.y, -v1.z);
return v; return v;
} }
public static Vector3 operator *(Vector3 v1, float d) public static Vector3 operator *(Vector3 v1, float d) {
{
Vector3 v = new Vector3(v1.x * d, v1.y * d, v1.z * d); Vector3 v = new Vector3(v1.x * d, v1.y * d, v1.z * d);
return v; return v;
} }
public static Vector3 operator *(float d, Vector3 v1) public static Vector3 operator *(float d, Vector3 v1) {
{
Vector3 v = new Vector3(d * v1.x, d * v1.y, d * v1.z); Vector3 v = new Vector3(d * v1.x, d * v1.y, d * v1.z);
return v; return v;
} }
public static Vector3 operator /(Vector3 v1, float d) public static Vector3 operator /(Vector3 v1, float d) {
{
Vector3 v = new Vector3(v1.x / d, v1.y / d, v1.z / d); Vector3 v = new Vector3(v1.x / d, v1.y / d, v1.z / d);
return v; return v;
} }
public bool Equals(Vector3 v) => (x == v.x && y == v.y && z == v.z); public bool Equals(Vector3 v) => (x == v.x && y == v.y && z == v.z);
public override bool Equals(object obj) public override bool Equals(object obj) {
{
if (!(obj is Vector3 v)) if (!(obj is Vector3 v))
return false; return false;
return (x == v.x && y == v.y && z == v.z); return (x == v.x && y == v.y && z == v.z);
} }
public static bool operator ==(Vector3 v1, Vector3 v2) public static bool operator ==(Vector3 v1, Vector3 v2) {
{
return (v1.x == v2.x && v1.y == v2.y && v1.z == v2.z); return (v1.x == v2.x && v1.y == v2.y && v1.z == v2.z);
} }
public static bool operator !=(Vector3 v1, Vector3 v2) public static bool operator !=(Vector3 v1, Vector3 v2) {
{
return (v1.x != v2.x || v1.y != v2.y || v1.z != v2.z); return (v1.x != v2.x || v1.y != v2.y || v1.z != v2.z);
} }
public override int GetHashCode() public override int GetHashCode() {
{
return (x, y, z).GetHashCode(); return (x, y, z).GetHashCode();
} }
public static float Distance(Vector3 v1, Vector3 v2) public static float Distance(Vector3 v1, Vector3 v2) {
{
return (v2 - v1).magnitude; return (v2 - v1).magnitude;
} }
public static float Dot(Vector3 v1, Vector3 v2) public static float Dot(Vector3 v1, Vector3 v2) {
{
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
} }
public static Vector3 Lerp(Vector3 v1, Vector3 v2, float f) public static Vector3 Lerp(Vector3 v1, Vector3 v2, float f) {
{
Vector3 v = v1 + (v2 - v1) * f; Vector3 v = v1 + (v2 - v1) * f;
return v; return v;
} }

View File

@ -1,10 +1,8 @@
using System; using System;
namespace LinearAlgebra namespace Passer.LinearAlgebra {
{
public class float16 public class float16 {
{
// //
// FILE: float16.cpp // FILE: float16.cpp
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
@ -16,14 +14,12 @@ namespace LinearAlgebra
public float16() { _value = 0; } public float16() { _value = 0; }
public float16(float f) public float16(float f) {
{
//_value = f32tof16(f); //_value = f32tof16(f);
_value = F32ToF16__(f); _value = F32ToF16__(f);
} }
public float toFloat() public float toFloat() {
{
return f16tof32(_value); return f16tof32(_value);
} }
@ -157,8 +153,7 @@ namespace LinearAlgebra
// //
// CORE CONVERSION // CORE CONVERSION
// //
float f16tof32(ushort _value) float f16tof32(ushort _value) {
{
//ushort sgn; //ushort sgn;
ushort man; ushort man;
int exp; int exp;
@ -173,13 +168,11 @@ namespace LinearAlgebra
//Debug.Log($"{sgn} {exp} {man}"); //Debug.Log($"{sgn} {exp} {man}");
// ZERO // ZERO
if ((_value & 0x7FFF) == 0) if ((_value & 0x7FFF) == 0) {
{
return sgn ? -0 : 0; return sgn ? -0 : 0;
} }
// NAN & INF // NAN & INF
if (exp == 0x001F) if (exp == 0x001F) {
{
if (man == 0) if (man == 0)
return sgn ? float.NegativeInfinity : float.PositiveInfinity; //-INFINITY : INFINITY; return sgn ? float.NegativeInfinity : float.PositiveInfinity; //-INFINITY : INFINITY;
else else
@ -193,50 +186,43 @@ namespace LinearAlgebra
f = 1; f = 1;
// PROCESS MANTISSE // PROCESS MANTISSE
for (int i = 9; i >= 0; i--) for (int i = 9; i >= 0; i--) {
{
f *= 2; f *= 2;
if ((man & (1 << i)) != 0) if ((man & (1 << i)) != 0)
f = f + 1; f = f + 1;
} }
//Debug.Log($"{f}"); //Debug.Log($"{f}");
f = f * (float)Math.Pow(2.0f, exp - 25); f = f * (float)Math.Pow(2.0f, exp - 25);
if (exp == 0) if (exp == 0) {
{
f = f * (float)Math.Pow(2.0f, -13); // 5.96046447754e-8; f = f * (float)Math.Pow(2.0f, -13); // 5.96046447754e-8;
} }
//Debug.Log($"{f}"); //Debug.Log($"{f}");
return sgn ? -f : f; return sgn ? -f : f;
} }
public static uint SingleToInt32Bits(float value) public static uint SingleToInt32Bits(float value) {
{
byte[] bytes = BitConverter.GetBytes(value); byte[] bytes = BitConverter.GetBytes(value);
if (BitConverter.IsLittleEndian) if (BitConverter.IsLittleEndian)
Array.Reverse(bytes); // If the system is little-endian, reverse the byte order Array.Reverse(bytes); // If the system is little-endian, reverse the byte order
return BitConverter.ToUInt32(bytes, 0); return BitConverter.ToUInt32(bytes, 0);
} }
public ushort F32ToF16__(float f) public ushort F32ToF16__(float f) {
{
uint t = BitConverter.ToUInt32(BitConverter.GetBytes(f), 0); uint t = BitConverter.ToUInt32(BitConverter.GetBytes(f), 0);
ushort man = (ushort)((t & 0x007FFFFF) >> 12); ushort man = (ushort)((t & 0x007FFFFF) >> 12);
int exp = (int)((t & 0x7F800000) >> 23); int exp = (int)((t & 0x7F800000) >> 23);
bool sgn = (t & 0x80000000) != 0; bool sgn = (t & 0x80000000) != 0;
// handle 0 // handle 0
if ((t & 0x7FFFFFFF) == 0) if ((t & 0x7FFFFFFF) == 0) {
{
return sgn ? (ushort)0x8000 : (ushort)0x0000; return sgn ? (ushort)0x8000 : (ushort)0x0000;
} }
// denormalized float32 does not fit in float16 // denormalized float32 does not fit in float16
if (exp == 0x00) if (exp == 0x00) {
{
return sgn ? (ushort)0x8000 : (ushort)0x0000; return sgn ? (ushort)0x8000 : (ushort)0x0000;
} }
// handle infinity & NAN // handle infinity & NAN
if (exp == 0x00FF) if (exp == 0x00FF) {
{
if (man != 0) if (man != 0)
return 0xFE00; // NAN return 0xFE00; // NAN
return sgn ? (ushort)0xFC00 : (ushort)0x7C00; // -INF : INF return sgn ? (ushort)0xFC00 : (ushort)0x7C00; // -INF : INF
@ -245,13 +231,11 @@ namespace LinearAlgebra
// normal numbers // normal numbers
exp = exp - 127 + 15; exp = exp - 127 + 15;
// overflow does not fit => INF // overflow does not fit => INF
if (exp > 30) if (exp > 30) {
{
return sgn ? (ushort)0xFC00 : (ushort)0x7C00; // -INF : INF return sgn ? (ushort)0xFC00 : (ushort)0x7C00; // -INF : INF
} }
// subnormal numbers // subnormal numbers
if (exp < -38) if (exp < -38) {
{
return sgn ? (ushort)0x8000 : (ushort)0x0000; // -0 or 0 ? just 0 ? return sgn ? (ushort)0x8000 : (ushort)0x0000; // -0 or 0 ? just 0 ?
} }
if (exp <= 0) // subnormal if (exp <= 0) // subnormal
@ -276,8 +260,7 @@ namespace LinearAlgebra
} }
//This function is faulty!!!! //This function is faulty!!!!
ushort f32tof16(float f) ushort f32tof16(float f) {
{
//uint t = *(uint*)&f; //uint t = *(uint*)&f;
//uint t = (uint)BitConverter.SingleToInt32Bits(f); //uint t = (uint)BitConverter.SingleToInt32Bits(f);
uint t = SingleToInt32Bits(f); uint t = SingleToInt32Bits(f);
@ -287,18 +270,15 @@ namespace LinearAlgebra
bool sgn = (t & 0x80000000) != 0; bool sgn = (t & 0x80000000) != 0;
// handle 0 // handle 0
if ((t & 0x7FFFFFFF) == 0) if ((t & 0x7FFFFFFF) == 0) {
{
return sgn ? (ushort)0x8000 : (ushort)0x0000; return sgn ? (ushort)0x8000 : (ushort)0x0000;
} }
// denormalized float32 does not fit in float16 // denormalized float32 does not fit in float16
if (exp == 0x00) if (exp == 0x00) {
{
return sgn ? (ushort)0x8000 : (ushort)0x0000; return sgn ? (ushort)0x8000 : (ushort)0x0000;
} }
// handle infinity & NAN // handle infinity & NAN
if (exp == 0x00FF) if (exp == 0x00FF) {
{
if (man != 0) if (man != 0)
return 0xFE00; // NAN return 0xFE00; // NAN
return sgn ? (ushort)0xFC00 : (ushort)0x7C00; // -INF : INF return sgn ? (ushort)0xFC00 : (ushort)0x7C00; // -INF : INF
@ -307,13 +287,11 @@ namespace LinearAlgebra
// normal numbers // normal numbers
exp = (short)(exp - 127 + 15); exp = (short)(exp - 127 + 15);
// overflow does not fit => INF // overflow does not fit => INF
if (exp > 30) if (exp > 30) {
{
return sgn ? (ushort)0xFC00 : (ushort)0x7C00; // -INF : INF return sgn ? (ushort)0xFC00 : (ushort)0x7C00; // -INF : INF
} }
// subnormal numbers // subnormal numbers
if (exp < -38) if (exp < -38) {
{
return sgn ? (ushort)0x8000 : (ushort)0x0000; // -0 or 0 ? just 0 ? return sgn ? (ushort)0x8000 : (ushort)0x0000; // -0 or 0 ? just 0 ?
} }
if (exp <= 0) // subnormal if (exp <= 0) // subnormal

View File

@ -1,17 +1,12 @@
#if NUNIT
using NUnit.Framework; using NUnit.Framework;
using Passer.LinearAlgebra;
namespace LinearAlgebra.Test namespace LinearAlgebraTest {
{ public class AngleTest {
public class Tests
{
[SetUp]
public void Setup()
{
}
[Test] [Test]
public void Test_Normalize() public void Normalize() {
{
float r = 0; float r = 0;
r = Angle.Normalize(90); r = Angle.Normalize(90);
@ -43,8 +38,7 @@ namespace LinearAlgebra.Test
} }
[Test] [Test]
public void Clamp() public void Clamp() {
{
float r = 0; float r = 0;
r = Angle.Clamp(1, 0, 2); r = Angle.Clamp(1, 0, 2);
@ -69,12 +63,11 @@ namespace LinearAlgebra.Test
Assert.AreEqual(r, 1, "Clamp 1 0 INFINITY"); Assert.AreEqual(r, 1, "Clamp 1 0 INFINITY");
r = Angle.Clamp(1, float.NegativeInfinity, 1); r = Angle.Clamp(1, float.NegativeInfinity, 1);
Assert.AreEqual(r, 1, "Clamp 1 -INFINITY 1"); Assert.AreEqual(r, 1, "Clamp 1 -INFINITY 1");
} }
[Test] [Test]
public void Difference() public void Difference() {
{
float r = 0; float r = 0;
r = Angle.Difference(0, 90); r = Angle.Difference(0, 90);
@ -112,8 +105,7 @@ namespace LinearAlgebra.Test
} }
[Test] [Test]
public void MoveTowards() public void MoveTowards() {
{
float r = 0; float r = 0;
r = Angle.MoveTowards(0, 90, 30); r = Angle.MoveTowards(0, 90, 30);
@ -166,4 +158,5 @@ namespace LinearAlgebra.Test
} }
} }
} }
#endif

View File

@ -1,15 +1,19 @@
using LinearAlgebra; using Passer.LinearAlgebra;
namespace RoboidControl { namespace RoboidControl
public class LowLevelMessages { {
public class LowLevelMessages
{
public static void SendSpherical(byte[] buffer, ref byte ix, Spherical v) { public static void SendSpherical(byte[] buffer, ref byte ix, Spherical v)
{
SendFloat16(buffer, ref ix, new float16(v.distance)); SendFloat16(buffer, ref ix, new float16(v.distance));
SendAngle8(buffer, ref ix, v.direction.horizontal); SendAngle8(buffer, ref ix, v.direction.horizontal);
SendAngle8(buffer, ref ix, v.direction.vertical); SendAngle8(buffer, ref ix, v.direction.vertical);
} }
public static Spherical ReceiveSpherical(byte[] data, ref byte ix) { public static Spherical ReceiveSpherical(byte[] data, ref byte ix)
{
float distance = ReceiveFloat16(data, ref ix); float distance = ReceiveFloat16(data, ref ix);
float horizontal = ReceiveAngle8(data, ref ix); float horizontal = ReceiveAngle8(data, ref ix);
float vertical = ReceiveAngle8(data, ref ix); float vertical = ReceiveAngle8(data, ref ix);
@ -17,17 +21,20 @@ namespace RoboidControl {
return v; return v;
} }
public static void SendQuat32(byte[] buffer, ref byte ix, SwingTwist s) { public static void SendQuat32(byte[] buffer, ref byte ix, SwingTwist s)
{
Quat32 q32 = Quat32.FromSwingTwist(s); Quat32 q32 = Quat32.FromSwingTwist(s);
SendQuat32(buffer, ref ix, q32); SendQuat32(buffer, ref ix, q32);
} }
public static void SendQuat32(byte[] buffer, ref byte ix, Quat32 q) { public static void SendQuat32(byte[] buffer, ref byte ix, Quat32 q)
{
int qx = (int)(q.x * 127 + 128); int qx = (int)(q.x * 127 + 128);
int qy = (int)(q.y * 127 + 128); int qy = (int)(q.y * 127 + 128);
int qz = (int)(q.z * 127 + 128); int qz = (int)(q.z * 127 + 128);
int qw = (int)(q.w * 255); int qw = (int)(q.w * 255);
if (q.w < 0) { if (q.w < 0)
{
qx = -qx; qx = -qx;
qy = -qy; qy = -qy;
qz = -qz; qz = -qz;
@ -39,7 +46,8 @@ namespace RoboidControl {
buffer[ix++] = (byte)qz; buffer[ix++] = (byte)qz;
buffer[ix++] = (byte)qw; buffer[ix++] = (byte)qw;
} }
public static Quat32 ReceiveQuat32(byte[] data, ref byte ix) { public static Quat32 ReceiveQuat32(byte[] data, ref byte ix)
{
Quat32 q = new Quat32( Quat32 q = new Quat32(
(data[ix++] - 128.0F) / 127.0F, (data[ix++] - 128.0F) / 127.0F,
(data[ix++] - 128.0F) / 127.0F, (data[ix++] - 128.0F) / 127.0F,
@ -48,7 +56,8 @@ namespace RoboidControl {
return q; return q;
} }
public static SwingTwist ReceiveSwingTwist(byte[] data, ref byte ix) { public static SwingTwist ReceiveSwingTwist(byte[] data, ref byte ix)
{
Quat32 q32 = ReceiveQuat32(data, ref ix); Quat32 q32 = ReceiveQuat32(data, ref ix);
// UnityEngine.Quaternion q = new(q32.x, q32.y, q32.z, q32.w); // UnityEngine.Quaternion q = new(q32.x, q32.y, q32.z, q32.w);
// SwingTwist r = new(q.eulerAngles.y, q.eulerAngles.x, q.eulerAngles.z); // SwingTwist r = new(q.eulerAngles.y, q.eulerAngles.x, q.eulerAngles.z);
@ -57,7 +66,8 @@ namespace RoboidControl {
return r; return r;
} }
public static void SendAngle8(byte[] buffer, ref byte ix, float angle) { public static void SendAngle8(byte[] buffer, ref byte ix, float angle)
{
// Normalize angle // Normalize angle
while (angle >= 180) while (angle >= 180)
angle -= 360; angle -= 360;
@ -67,24 +77,28 @@ namespace RoboidControl {
buffer[ix++] = (byte)value; buffer[ix++] = (byte)value;
} }
public static float ReceiveAngle8(byte[] data, ref byte ix) { public static float ReceiveAngle8(byte[] data, ref byte ix)
{
float value = (data[ix++] * 180) / 128.0F; float value = (data[ix++] * 180) / 128.0F;
return value; return value;
} }
public static void SendFloat16(byte[] data, ref byte ix, float f) { public static void SendFloat16(byte[] data, ref byte ix, float f)
{
float16 f16 = new float16(f); float16 f16 = new float16(f);
ushort binary = f16.GetBinary(); ushort binary = f16.GetBinary();
data[ix++] = (byte)(binary >> 8); data[ix++] = (byte)(binary >> 8);
data[ix++] = (byte)(binary & 255); data[ix++] = (byte)(binary & 255);
} }
public static void SendFloat16(byte[] data, ref byte ix, float16 f) { public static void SendFloat16(byte[] data, ref byte ix, float16 f)
{
ushort binary = f.GetBinary(); ushort binary = f.GetBinary();
data[ix++] = (byte)((binary >> 8) & 0xFF); data[ix++] = (byte)((binary >> 8) & 0xFF);
data[ix++] = (byte)(binary & 0xFF); data[ix++] = (byte)(binary & 0xFF);
} }
public static float ReceiveFloat16(byte[] data, ref byte ix) { public static float ReceiveFloat16(byte[] data, ref byte ix)
{
byte msb = data[ix++]; byte msb = data[ix++];
byte lsb = data[ix++]; byte lsb = data[ix++];
ushort value = (ushort)(msb << 8 | lsb); ushort value = (ushort)(msb << 8 | lsb);

View File

@ -1,4 +1,4 @@
using LinearAlgebra; using Passer.LinearAlgebra;
namespace RoboidControl { namespace RoboidControl {

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using LinearAlgebra; using System.Diagnostics;
using Passer.LinearAlgebra;
namespace RoboidControl { namespace RoboidControl {