public static FInt Asin(FInt F) { bool isNegative = F < 0; F = Abs(F); if (F > FInt.OneF) { throw new ArithmeticException("Bad Asin Input:" + F.ToDouble()); } FInt f1 = mul(mul(mul(mul(FInt.Create(145103 >> FInt.SHIFT_AMOUNT, false), F) - FInt.Create(599880 >> FInt.SHIFT_AMOUNT, false), F) + FInt.Create(1420468 >> FInt.SHIFT_AMOUNT, false), F) - FInt.Create(3592413 >> FInt.SHIFT_AMOUNT, false), F) + FInt.Create(26353447 >> FInt.SHIFT_AMOUNT, false); FInt f2 = PI / FInt.Create(2, true) - (Sqrt(FInt.OneF - F) * f1); return(isNegative ? f2.Inverse : f2); }
// Rotates degree to targetDegree (between 0 and 360), taking the shortest distance. Lerp argument is amount to rotate by. // Note: Lerp of 0.5 may be good place to start. public static FInt RotateTo(FInt degree, FInt targetDegree, FInt lerp) { FInt diff = targetDegree - degree + 360; // Return Target Degree if it's been matched. if (FInt.Abs(diff) <= lerp) { return(targetDegree); } // Otherwise, return next step: if (diff > 0) { degree += lerp; } else { degree -= lerp; } return(FPDegrees.Normalize(degree)); }
public static FInt Atan2(FInt F1, FInt F2) { if (F2.RawValue == 0 && F1.RawValue == 0) { return((FInt)0); } FInt result = (FInt)0; if (F2 > 0) { result = Atan(F1 / F2); } else if (F2 < 0) { result = (F1 >= 0) ? (PI - Atan(Abs(F1 / F2))) : (PI - Atan(Abs(F1 / F2))).Inverse; } else { result = (F1 >= 0 ? PI : PI.Inverse) / FInt.Create(2, true); } return(result); }
// Sin public static FInt Sin(FInt i) { FInt j = (FInt)0; for (; i < 0; i += FInt.Create(25736, false)) { ; } if (i > FInt.Create(25736, false)) { i %= FInt.Create(25736, false); } FInt k = (i * FInt.Create(10, false)) / FInt.Create(714, false); if (i != 0 && i != FInt.Create(6434, false) && i != FInt.Create(12868, false) && i != FInt.Create(19302, false) && i != FInt.Create(25736, false)) { j = (i * FInt.Create(100, false)) / FInt.Create(714, false) - k * FInt.Create(10, false); } if (k <= FInt.Create(90, false)) { return(SinLookup(k, j)); } if (k <= FInt.Create(180, false)) { return(SinLookup(FInt.Create(180, false) - k, j)); } if (k <= FInt.Create(270, false)) { return(SinLookup(k - FInt.Create(180, false), j).Inverse); } else { return(SinLookup(FInt.Create(360, false) - k, j).Inverse); } }
public static FInt PIOver180F = PI / (FInt)180; //PI / 180 // Square Root public static FInt Sqrt(FInt f, int NumberOfIterations) { if (f.RawValue < 0) //NaN in Math.Sqrt { throw new ArithmeticException("Input Error"); } if (f.RawValue == 0) { return((FInt)0); } FInt k = f + FInt.OneF >> 1; for (int i = 0; i < NumberOfIterations; i++) { k = (k + (f / k)) >> 1; } if (k.RawValue < 0) { throw new ArithmeticException("Overflow"); } return(k); }
public static FInt GetYFromRotation(FInt degrees, FInt distance) { return(FPRadians.GetYFromRotation(FPDegrees.ConvertToRadians(degrees), distance)); }
// Reverse the angle public static FInt Reverse(FInt degrees) { return(FPDegrees.Normalize(degrees + 180)); }
// Quadratic Bezier Interpolation // https://en.wikipedia.org/wiki/Bezier_curve // p0, p1, p2 are Start Point, Control Point, End Point public static FInt QuadBezier(FInt p0, FInt p1, FInt p2, FInt weight) { FInt k = 1 - weight; return((k * k * p0) + (2 * (1 - weight) * weight * p1) + (weight * weight * p2)); }
public static FInt GetYOffsetFromRotation(FInt radian, int xOffset, int yOffset) { return(-yOffset *FInt.Cos(radian) + xOffset * FInt.Sin(radian)); }
public static FInt GetYFromRotation(FInt radian, FInt distance) { return(distance * FInt.Sin(radian)); }
// Reverse / Invert Radians public static FInt Reverse(FInt radian) { return(FPRadians.Normalize(radian + FInt.PI)); }
// Shift degrees to valid ranges. public static FInt Wrap(FInt radian) { return(FPSpectrum.Wrap(radian, FInt.PI, FInt.PI)); }
// Get the speed needed to cover a distance over the time provided. public static FInt Speed(FInt distance, FInt time) { return(distance / time); }
// Conversions public static FInt ConvertToRadians(FInt degrees) { return(degrees * FInt.PI / 180); }
public static FInt Tan(FInt i) { return(Sin(i) / Cos(i)); }
// Cos, Tan, Asin public static FInt Cos(FInt i) { return(Sin(i + FInt.Create(6435, false))); }
private static FInt mul(FInt F1, FInt F2) { return(F1 * F2); }
public static FInt operator >>(FInt one, int Amount) { return(FInt.Create(one.RawValue >> Amount, false)); }
// Find the degrees between two coordinates public static FInt GetDegreesBetweenCoords(int x1, int y1, int x2, int y2) { return(FInt.Atan2(FInt.Create(y2 - y1), FInt.Create(x2 - x1)) * 180 / FInt.PI); }
// ATan, ATan2 public static FInt Atan(FInt F) { return(Asin(F / Sqrt(FInt.OneF + (F * F)))); }
public static FInt ConvertToPercent(FInt radian) { return(FPSpectrum.GetPercentFromValue(FPRadians.Wrap(radian), (0 - FInt.PI), FInt.PI)); }
// Abs public static FInt Abs(FInt F) { return((F < 0) ? F.Inverse : F); }
// Normalize radians to valid range: 0 to 2pi public static FInt Normalize(FInt radian) { radian %= (2 * FInt.PI); return(radian >= 0 ? radian : radian + (2 * FInt.PI)); }
public static FInt ConvertToPercent(FInt degrees) { return(FPSpectrum.GetPercentFromValue(FPRadians.Wrap(degrees), FInt.Create(-180), FInt.Create(180))); }
// Find the radians between two coordinates public static FInt GetRadiansBetweenCoords(int x1, int y1, int x2, int y2) { return(FInt.Atan2(FInt.Create(y2 - y1), FInt.Create(x2 - x1))); }
// Shift degrees to valid ranges. public static FInt Wrap(FInt degrees) { return(FPSpectrum.Wrap(degrees, FInt.Create(-180), FInt.Create(180))); }
// Convert between degrees and percent public static FInt ConvertToDegrees(FInt radian) { return(radian * 180 / FInt.PI); }
public static FInt Normalize(FInt degrees) { return(FPSpectrum.Wrap(degrees, FInt.Create(0), FInt.Create(360))); }
// Rotate a Radian public static FInt Rotate(FInt radian, FInt rotate) { return((radian + rotate) % (FInt.PI * 2)); }
// Get value between two numbers using weight factor (0 to 1); public static FInt Number(FInt val1, FInt val2, FInt weight) { return((1 - weight) * val1 + weight * val2); }