From 8209051a3ce5764ae3102bbdd39717dc5f5f8759 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Wed, 29 Mar 2023 10:06:37 -0700 Subject: [PATCH] remove non-static Normalize + return identity on zero vector --- src/Math/Fixed/Matrix4x4.cs | 4 +- src/Math/Fixed/Quaternion.cs | 33 ++++------- src/Math/Fixed/Transform2D.cs | 105 ---------------------------------- src/Math/Fixed/Vector2.cs | 19 +++--- src/Math/Fixed/Vector3.cs | 28 +++------ src/Math/Float/Matrix4x4.cs | 14 ++--- src/Math/Float/Transform2D.cs | 105 ---------------------------------- src/Math/Float/Vector2.cs | 19 +++--- src/Math/Float/Vector3.cs | 28 +++------ src/Math/Float/Vector4.cs | 50 +++++++--------- 10 files changed, 71 insertions(+), 334 deletions(-) delete mode 100644 src/Math/Fixed/Transform2D.cs delete mode 100644 src/Math/Float/Transform2D.cs diff --git a/src/Math/Fixed/Matrix4x4.cs b/src/Math/Fixed/Matrix4x4.cs index 8e6ad2ac..583d6840 100644 --- a/src/Math/Fixed/Matrix4x4.cs +++ b/src/Math/Fixed/Matrix4x4.cs @@ -996,8 +996,8 @@ namespace MoonWorks.Math.Fixed z = Vector3.Normalize(forward); Vector3.Cross(ref forward, ref up, out x); Vector3.Cross(ref x, ref forward, out y); - x.Normalize(); - y.Normalize(); + x = Vector3.Normalize(x); + y = Vector3.Normalize(y); result = new Matrix4x4(); result.Right = x; diff --git a/src/Math/Fixed/Quaternion.cs b/src/Math/Fixed/Quaternion.cs index 027a53f6..aa43ebe9 100644 --- a/src/Math/Fixed/Quaternion.cs +++ b/src/Math/Fixed/Quaternion.cs @@ -214,23 +214,6 @@ namespace MoonWorks.Math.Fixed ); } - /// - /// Scales the quaternion magnitude to unit length. - /// - public void Normalize() - { - Fix64 num = Fix64.One / (Fix64.Sqrt( - (X * X) + - (Y * Y) + - (Z * Z) + - (W * W) - )); - this.X *= num; - this.Y *= num; - this.Z *= num; - this.W *= num; - } - /// /// Returns a representation of this in the format: /// {X:[] Y:[] Z:[] W:[]} @@ -759,12 +742,16 @@ namespace MoonWorks.Math.Fixed /// The unit length quaternion an output parameter. public static void Normalize(ref Quaternion quaternion, out Quaternion result) { - Fix64 num = Fix64.One / (Fix64.Sqrt( - (quaternion.X * quaternion.X) + - (quaternion.Y * quaternion.Y) + - (quaternion.Z * quaternion.Z) + - (quaternion.W * quaternion.W) - )); + Fix64 lengthSquared = (quaternion.X * quaternion.X) + (quaternion.Y * quaternion.Y) + + (quaternion.Z * quaternion.Z) + (quaternion.W * quaternion.W); + + if (lengthSquared == Fix64.Zero) + { + result = Identity; + return; + } + + Fix64 num = Fix64.One / Fix64.Sqrt(lengthSquared); result.X = quaternion.X * num; result.Y = quaternion.Y * num; result.Z = quaternion.Z * num; diff --git a/src/Math/Fixed/Transform2D.cs b/src/Math/Fixed/Transform2D.cs deleted file mode 100644 index 208b3581..00000000 --- a/src/Math/Fixed/Transform2D.cs +++ /dev/null @@ -1,105 +0,0 @@ -namespace MoonWorks.Math.Fixed -{ - public struct Transform2D : System.IEquatable - { - public Vector2 Position { get; } - public Fix64 Rotation { get; } - public Vector2 Scale { get; } - - private bool transformMatrixCalculated; - private Matrix3x2 transformMatrix; - - public Matrix3x2 TransformMatrix - { - get - { - if (!transformMatrixCalculated) - { - transformMatrix = CreateTransformMatrix(Position, Rotation, Scale); - transformMatrixCalculated = true; - } - - return transformMatrix; - } - } - - public bool IsAxisAligned => Rotation % Fix64.PiOver2 == Fix64.Zero; - public bool IsUniformScale => Scale.X == Scale.Y || Scale.X == -Scale.Y; - - public static readonly Transform2D Identity = new Transform2D(Vector2.Zero, Fix64.Zero, Vector2.One); - - public Transform2D(Vector2 position) - { - Position = position; - Rotation = Fix64.Zero; - Scale = Vector2.One; - transformMatrixCalculated = false; - transformMatrix = Matrix3x2.Identity; - } - - public Transform2D(Vector2 position, Fix64 rotation) - { - Position = position; - Rotation = rotation; - Scale = Vector2.One; - transformMatrixCalculated = false; - transformMatrix = Matrix3x2.Identity; - } - - public Transform2D(Vector2 position, Fix64 rotation, Vector2 scale) - { - Position = position; - Rotation = rotation; - Scale = scale; - transformMatrixCalculated = false; - transformMatrix = Matrix3x2.Identity; - } - - public Transform2D Compose(Transform2D other) - { - return new Transform2D(Position + other.Position, Rotation + other.Rotation, Scale * other.Scale); - } - - private static Matrix3x2 CreateTransformMatrix(Vector2 position, Fix64 rotation, Vector2 scale) - { - return - Matrix3x2.CreateScale(scale) * - Matrix3x2.CreateRotation(rotation) * - Matrix3x2.CreateTranslation(position); - } - - public bool Equals(Transform2D other) - { - return - Position == other.Position && - Rotation == other.Rotation && - Scale == other.Scale; - } - - - public override bool Equals(System.Object other) - { - if (other is Transform2D otherTransform) - { - return Equals(otherTransform); - } - - return false; - } - - public override int GetHashCode() - { - return System.HashCode.Combine(Position, Rotation, Scale); - } - - public static bool operator ==(Transform2D a, Transform2D b) - { - return a.Equals(b); - } - - public static bool operator !=(Transform2D a, Transform2D b) - { - return !a.Equals(b); - } - } -} diff --git a/src/Math/Fixed/Vector2.cs b/src/Math/Fixed/Vector2.cs index b05a733d..a551015f 100644 --- a/src/Math/Fixed/Vector2.cs +++ b/src/Math/Fixed/Vector2.cs @@ -200,16 +200,6 @@ namespace MoonWorks.Math.Fixed return (X * X) + (Y * Y); } - /// - /// Turns this to a unit vector with the same direction. - /// - public void Normalize() - { - Fix64 val = Fix64.One / Fix64.Sqrt((X * X) + (Y * Y)); - X *= val; - Y *= val; - } - /// /// Turns this to an angle in radians. /// @@ -423,7 +413,14 @@ namespace MoonWorks.Math.Fixed /// Unit vector. public static Vector2 Normalize(Vector2 value) { - Fix64 val = Fix64.One / Fix64.Sqrt((value.X * value.X) + (value.Y * value.Y)); + Fix64 lengthSquared = (value.X * value.X) + (value.Y * value.Y); + + if (lengthSquared == Fix64.Zero) + { + return Zero; + } + + Fix64 val = Fix64.One / Fix64.Sqrt(lengthSquared); value.X *= val; value.Y *= val; return value; diff --git a/src/Math/Fixed/Vector3.cs b/src/Math/Fixed/Vector3.cs index fc9bddc5..f534289f 100644 --- a/src/Math/Fixed/Vector3.cs +++ b/src/Math/Fixed/Vector3.cs @@ -309,21 +309,6 @@ namespace MoonWorks.Math.Fixed return (X * X) + (Y * Y) + (Z * Z); } - /// - /// Turns this to a unit vector with the same direction. - /// - public void Normalize() - { - Fix64 factor = Fix64.One / Fix64.Sqrt( - (X * X) + - (Y * Y) + - (Z * Z) - ); - X *= factor; - Y *= factor; - Z *= factor; - } - /// /// Returns a representation of this in the format: /// {X:[] Y:[] Z:[]} @@ -733,11 +718,14 @@ namespace MoonWorks.Math.Fixed /// Unit vector. public static Vector3 Normalize(Vector3 value) { - Fix64 factor = Fix64.One / Fix64.Sqrt( - (value.X * value.X) + - (value.Y * value.Y) + - (value.Z * value.Z) - ); + Fix64 lengthSquared = (value.X * value.X) + (value.Y * value.Y) + (value.Z * value.Z); + + if (lengthSquared == Fix64.Zero) + { + return Zero; + } + + Fix64 factor = Fix64.One / Fix64.Sqrt(lengthSquared); return new Vector3( value.X * factor, value.Y * factor, diff --git a/src/Math/Float/Matrix4x4.cs b/src/Math/Float/Matrix4x4.cs index 4ec27ec6..8a12769d 100644 --- a/src/Math/Float/Matrix4x4.cs +++ b/src/Math/Float/Matrix4x4.cs @@ -611,7 +611,7 @@ namespace MoonWorks.Math.Float ); } Vector3.Cross(ref cameraUpVector, ref vector, out vector3); - vector3.Normalize(); + vector3 = Vector3.Normalize(vector3); Vector3.Cross(ref vector, ref vector3, out vector2); result.M11 = vector3.X; result.M12 = vector3.Y; @@ -730,16 +730,16 @@ namespace MoonWorks.Math.Float Vector3.Forward; } Vector3.Cross(ref rotateAxis, ref vector, out vector3); - vector3.Normalize(); + vector3 = Vector3.Normalize(vector3); Vector3.Cross(ref vector3, ref rotateAxis, out vector); - vector.Normalize(); + vector = Vector3.Normalize(vector); } else { Vector3.Cross(ref rotateAxis, ref vector2, out vector3); - vector3.Normalize(); + vector3 = Vector3.Normalize(vector3); Vector3.Cross(ref vector3, ref vector4, out vector); - vector.Normalize(); + vector = Vector3.Normalize(vector); } result.M11 = vector3.X; @@ -1701,8 +1701,8 @@ namespace MoonWorks.Math.Float Vector3.Normalize(ref forward, out z); Vector3.Cross(ref forward, ref up, out x); Vector3.Cross(ref x, ref forward, out y); - x.Normalize(); - y.Normalize(); + x = Vector3.Normalize(x); + y = Vector3.Normalize(y); result = new Matrix4x4(); result.Right = x; diff --git a/src/Math/Float/Transform2D.cs b/src/Math/Float/Transform2D.cs deleted file mode 100644 index 1de4545c..00000000 --- a/src/Math/Float/Transform2D.cs +++ /dev/null @@ -1,105 +0,0 @@ -namespace MoonWorks.Math.Float -{ - public struct Transform2D : System.IEquatable - { - public Vector2 Position { get; } - public float Rotation { get; } - public Vector2 Scale { get; } - - private bool transformMatrixCalculated; - private Matrix3x2 transformMatrix; - - public Matrix3x2 TransformMatrix - { - get - { - if (!transformMatrixCalculated) - { - transformMatrix = CreateTransformMatrix(Position, Rotation, Scale); - transformMatrixCalculated = true; - } - - return transformMatrix; - } - } - - public bool IsAxisAligned => Rotation % MathHelper.PiOver2 == 0; - public bool IsUniformScale => Scale.X == Scale.Y; - - public static readonly Transform2D Identity = new Transform2D(Vector2.Zero, 0, Vector2.One); - - public Transform2D(Vector2 position) - { - Position = position; - Rotation = 0; - Scale = Vector2.One; - transformMatrixCalculated = false; - transformMatrix = Matrix3x2.Identity; - } - - public Transform2D(Vector2 position, float rotation) - { - Position = position; - Rotation = rotation; - Scale = Vector2.One; - transformMatrixCalculated = false; - transformMatrix = Matrix3x2.Identity; - } - - public Transform2D(Vector2 position, float rotation, Vector2 scale) - { - Position = position; - Rotation = rotation; - Scale = scale; - transformMatrixCalculated = false; - transformMatrix = Matrix3x2.Identity; - } - - public Transform2D Compose(Transform2D other) - { - return new Transform2D(Position + other.Position, Rotation + other.Rotation, Scale * other.Scale); - } - - private static Matrix3x2 CreateTransformMatrix(Vector2 position, float rotation, Vector2 scale) - { - return - Matrix3x2.CreateScale(scale) * - Matrix3x2.CreateRotation(rotation) * - Matrix3x2.CreateTranslation(position); - } - - public bool Equals(Transform2D other) - { - return - Position == other.Position && - Rotation == other.Rotation && - Scale == other.Scale; - } - - - public override bool Equals(System.Object other) - { - if (other is Transform2D otherTransform) - { - return Equals(otherTransform); - } - - return false; - } - - public override int GetHashCode() - { - return System.HashCode.Combine(Position, Rotation, Scale); - } - - public static bool operator ==(Transform2D a, Transform2D b) - { - return a.Equals(b); - } - - public static bool operator !=(Transform2D a, Transform2D b) - { - return !a.Equals(b); - } - } -} diff --git a/src/Math/Float/Vector2.cs b/src/Math/Float/Vector2.cs index e4e52be7..85bc0c8c 100644 --- a/src/Math/Float/Vector2.cs +++ b/src/Math/Float/Vector2.cs @@ -194,16 +194,6 @@ namespace MoonWorks.Math.Float return (X * X) + (Y * Y); } - /// - /// Turns this to a unit vector with the same direction. - /// - public void Normalize() - { - float val = 1.0f / (float) System.Math.Sqrt((X * X) + (Y * Y)); - X *= val; - Y *= val; - } - /// /// Turns this to an angle in radians. /// @@ -717,7 +707,14 @@ namespace MoonWorks.Math.Float /// Unit vector. public static Vector2 Normalize(Vector2 value) { - float val = 1.0f / (float) System.Math.Sqrt((value.X * value.X) + (value.Y * value.Y)); + float lengthSquared = (value.X * value.X) + (value.Y * value.Y); + + if (lengthSquared == 0) + { + return Zero; + } + + float val = 1.0f / System.MathF.Sqrt(lengthSquared); value.X *= val; value.Y *= val; return value; diff --git a/src/Math/Float/Vector3.cs b/src/Math/Float/Vector3.cs index b2055cab..b845a3e5 100644 --- a/src/Math/Float/Vector3.cs +++ b/src/Math/Float/Vector3.cs @@ -302,21 +302,6 @@ namespace MoonWorks.Math.Float return (X * X) + (Y * Y) + (Z * Z); } - /// - /// Turns this to a unit vector with the same direction. - /// - public void Normalize() - { - float factor = 1.0f / (float) System.Math.Sqrt( - (X * X) + - (Y * Y) + - (Z * Z) - ); - X *= factor; - Y *= factor; - Z *= factor; - } - /// /// Returns a representation of this in the format: /// {X:[] Y:[] Z:[]} @@ -900,11 +885,14 @@ namespace MoonWorks.Math.Float /// Unit vector. public static Vector3 Normalize(Vector3 value) { - float factor = 1.0f / (float) System.Math.Sqrt( - (value.X * value.X) + - (value.Y * value.Y) + - (value.Z * value.Z) - ); + float lengthSquared = (value.X * value.X) + (value.Y * value.Y) + (value.Z * value.Z); + + if (lengthSquared == 0f) + { + return Zero; + } + + float factor = 1.0f / System.MathF.Sqrt(lengthSquared); return new Vector3( value.X * factor, value.Y * factor, diff --git a/src/Math/Float/Vector4.cs b/src/Math/Float/Vector4.cs index 263ecaca..a65cfb0a 100644 --- a/src/Math/Float/Vector4.cs +++ b/src/Math/Float/Vector4.cs @@ -267,23 +267,6 @@ namespace MoonWorks.Math.Float return (X * X) + (Y * Y) + (Z * Z) + (W * W); } - /// - /// Turns this to a unit vector with the same direction. - /// - public void Normalize() - { - float factor = 1.0f / (float) System.Math.Sqrt( - (X * X) + - (Y * Y) + - (Z * Z) + - (W * W) - ); - X *= factor; - Y *= factor; - Z *= factor; - W *= factor; - } - public override string ToString() { return ( @@ -853,12 +836,15 @@ namespace MoonWorks.Math.Float /// Unit vector. public static Vector4 Normalize(Vector4 vector) { - float factor = 1.0f / (float) System.Math.Sqrt( - (vector.X * vector.X) + - (vector.Y * vector.Y) + - (vector.Z * vector.Z) + - (vector.W * vector.W) - ); + var lengthSquared = (vector.X * vector.X) + (vector.Y * vector.Y) + + (vector.Z * vector.Z) + (vector.W * vector.W); + + if (lengthSquared == 0) + { + return Zero; + } + + float factor = 1.0f / System.MathF.Sqrt(lengthSquared); return new Vector4( vector.X * factor, vector.Y * factor, @@ -870,16 +856,20 @@ namespace MoonWorks.Math.Float /// /// Creates a new that contains a normalized values from another vector. /// - /// Source . + /// Source . /// Unit vector as an output parameter. public static void Normalize(ref Vector4 vector, out Vector4 result) { - float factor = 1.0f / (float) System.Math.Sqrt( - (vector.X * vector.X) + - (vector.Y * vector.Y) + - (vector.Z * vector.Z) + - (vector.W * vector.W) - ); + float lengthSquared = (vector.X * vector.X) + (vector.Y * vector.Y) + + (vector.Z * vector.Z) + (vector.W * vector.W); + + if (lengthSquared == 0) + { + result = Zero; + return; + } + + float factor = 1.0f / System.MathF.Sqrt(lengthSquared); result.X = vector.X * factor; result.Y = vector.Y * factor; result.Z = vector.Z * factor;