fractional constructor

pull/19/head
cosmonaut 2022-05-04 13:08:31 -07:00
parent 40e4be6d36
commit 41d1c593cf
3 changed files with 53 additions and 3 deletions

View File

@ -141,7 +141,7 @@ namespace MoonWorks.Collision.Fixed
if (shapeB == null) { throw new System.ArgumentNullException(nameof(shapeB)); } if (shapeB == null) { throw new System.ArgumentNullException(nameof(shapeB)); }
if (!simplex.TwoSimplex) { throw new System.ArgumentException("Simplex must be a 2-Simplex.", nameof(simplex)); } if (!simplex.TwoSimplex) { throw new System.ArgumentException("Simplex must be a 2-Simplex.", nameof(simplex)); }
var epsilon = Fix64.One / new Fix64(10000); var epsilon = Fix64.FromFraction(1, 10000);
var a = simplex.A; var a = simplex.A;
var b = simplex.B.Value; var b = simplex.B.Value;

View File

@ -40,6 +40,14 @@ namespace MoonWorks.Math.Fixed
RawValue = value * ONE; RawValue = value * ONE;
} }
/// <summary>
/// Create a fractional Fix64 number of the value (numerator / denominator).
/// </summary>
public static Fix64 FromFraction(int numerator, int denominator)
{
return new Fix64(numerator) / new Fix64(denominator);
}
/// <summary> /// <summary>
/// Returns an int indicating the sign of a Fix64 number. /// Returns an int indicating the sign of a Fix64 number.
/// </summary> /// </summary>
@ -73,18 +81,28 @@ namespace MoonWorks.Math.Fixed
return new Fix64((value.RawValue + mask) ^ mask); return new Fix64((value.RawValue + mask) ^ mask);
} }
/// <summary>
/// Returns the largest integral value less than or equal to the specified number.
/// </summary>
public static Fix64 Floor(Fix64 value) public static Fix64 Floor(Fix64 value)
{ {
// Zero out the fractional part. // Zero out the fractional part.
return new Fix64((long)((ulong)value.RawValue & 0xFFFFFFFF00000000)); return new Fix64((long)((ulong)value.RawValue & 0xFFFFFFFF00000000));
} }
/// <summary>
/// Returns the smallest integral value that is greater than or equal to the specified number.
/// </summary>
public static Fix64 Ceiling(Fix64 value) public static Fix64 Ceiling(Fix64 value)
{ {
var hasFractionalPart = (value.RawValue & 0x00000000FFFFFFFF) != 0; var hasFractionalPart = (value.RawValue & 0x00000000FFFFFFFF) != 0;
return hasFractionalPart ? Floor(value) + One : value; return hasFractionalPart ? Floor(value) + One : value;
} }
/// <summary>
/// Rounds to the nearest integral value.
/// If the value is halfway between an even and an uneven value, returns the even value.
/// </summary>
public static Fix64 Round(Fix64 value) public static Fix64 Round(Fix64 value)
{ {
var fractionalPart = value.RawValue & 0x00000000FFFFFFFF; var fractionalPart = value.RawValue & 0x00000000FFFFFFFF;
@ -104,22 +122,35 @@ namespace MoonWorks.Math.Fixed
: integralPart + One; : integralPart + One;
} }
//Formula taken from https://docs.microsoft.com/en-us/dotnet/api/system.math.ieeeremainder?view=net-6.0 /// <summary>
/// Returns a remainder value as defined by the IEEE remainder method.
/// </summary>
/// <returns></returns>
public static Fix64 IEEERemainder(Fix64 dividend, Fix64 divisor) public static Fix64 IEEERemainder(Fix64 dividend, Fix64 divisor)
{ {
//Formula taken from https://docs.microsoft.com/en-us/dotnet/api/system.math.ieeeremainder?view=net-6.0
return dividend - (divisor * Round(dividend / divisor)); return dividend - (divisor * Round(dividend / divisor));
} }
/// <summary>
/// Returns the minimum of two given Fix64 values.
/// </summary>
public static Fix64 Min(Fix64 x, Fix64 y) public static Fix64 Min(Fix64 x, Fix64 y)
{ {
return (x < y) ? x : y; return (x < y) ? x : y;
} }
/// <summary>
/// Returns the maximum of two given Fix64 values.
/// </summary>
public static Fix64 Max(Fix64 x, Fix64 y) public static Fix64 Max(Fix64 x, Fix64 y)
{ {
return (x > y) ? x : y; return (x > y) ? x : y;
} }
/// <summary>
/// Returns a value that is neither greater than nor less than a given min and max value.
/// </summary>
public static Fix64 Clamp(Fix64 value, Fix64 min, Fix64 max) public static Fix64 Clamp(Fix64 value, Fix64 min, Fix64 max)
{ {
return Fix64.Min(Fix64.Max(value, min), max); return Fix64.Min(Fix64.Max(value, min), max);
@ -127,6 +158,10 @@ namespace MoonWorks.Math.Fixed
// Trigonometry functions // Trigonometry functions
/// <summary>
/// Returns the square root of the given Fix64 value.
/// </summary>
/// <exception cref="ArgumentOutOfRangeException">Throws if x is less than zero.</exception>
public static Fix64 Sqrt(Fix64 x) public static Fix64 Sqrt(Fix64 x)
{ {
var xl = x.RawValue; var xl = x.RawValue;
@ -238,6 +273,9 @@ namespace MoonWorks.Math.Fixed
return clampedPiOver2; return clampedPiOver2;
} }
/// <summary>
/// Returns the sine of the specified angle.
/// </summary>
public static Fix64 Sin(Fix64 x) public static Fix64 Sin(Fix64 x)
{ {
var clampedL = ClampSinValue(x.RawValue, out var flipHorizontal, out var flipVertical); var clampedL = ClampSinValue(x.RawValue, out var flipHorizontal, out var flipVertical);
@ -262,6 +300,9 @@ namespace MoonWorks.Math.Fixed
return new Fix64(finalValue); return new Fix64(finalValue);
} }
/// <summary>
/// Returns the cosine of the specified angle.
/// </summary>
public static Fix64 Cos(Fix64 x) public static Fix64 Cos(Fix64 x)
{ {
var xl = x.RawValue; var xl = x.RawValue;
@ -269,6 +310,9 @@ namespace MoonWorks.Math.Fixed
return Sin(new Fix64(rawAngle)); return Sin(new Fix64(rawAngle));
} }
/// <summary>
/// Returns the tangent of the specified angle.
/// </summary>
public static Fix64 Tan(Fix64 x) public static Fix64 Tan(Fix64 x)
{ {
var clampedPi = x.RawValue % PI; var clampedPi = x.RawValue % PI;
@ -300,6 +344,9 @@ namespace MoonWorks.Math.Fixed
return new Fix64(finalValue); return new Fix64(finalValue);
} }
/// <summary>
/// Returns the angle whose tangent is the specified number.
/// </summary>
public static Fix64 Atan(Fix64 z) public static Fix64 Atan(Fix64 z)
{ {
if (z.RawValue == 0) return Zero; if (z.RawValue == 0) return Zero;
@ -354,6 +401,9 @@ namespace MoonWorks.Math.Fixed
return result; return result;
} }
/// <summary>
/// Returns the angle whose tangent is the quotient of two specified numbers.
/// </summary>
public static Fix64 Atan2(Fix64 y, Fix64 x) public static Fix64 Atan2(Fix64 y, Fix64 x)
{ {
var yl = y.RawValue; var yl = y.RawValue;

View File

@ -51,7 +51,7 @@ namespace MoonWorks.Math.Fixed
0, 0 0, 0
); );
private static readonly Fix64 RotationEpsilon = (Fix64.One / new Fix64(1000)) * (Fix64.Pi / new Fix64(180)); private static readonly Fix64 RotationEpsilon = Fix64.FromFraction(1, 1000) * (Fix64.Pi / new Fix64(180));
/// <summary> /// <summary>
/// Returns the multiplicative identity matrix. /// Returns the multiplicative identity matrix.