/// <summary> /// Create a fixed-int number from parts. For example, to create 1.5 pass in 1 and 500. /// </summary> /// <param name="PreDecimal">The number above the decimal. For 1.5, this would be 1.</param> /// <param name="PostDecimal">The number below the decimal, to three digits. /// For 1.5, this would be 500. For 1.005, this would be 5.</param> /// <returns>A fixed-int representation of the number parts</returns> public static FInt FromParts(int PreDecimal, int PostDecimal) { FInt f = new FInt(PreDecimal); if (PostDecimal != 0) f.RawValue += (new FInt(PostDecimal) / 1000).RawValue; return f; }
public FInt LengthSquared(out FInt i) { FInt.Multiply(ref X, ref X, out scratch1); FInt.Multiply(ref Y, ref Y, out scratch2); FInt.Add(ref scratch1, ref scratch2, out i); return i; }
public static void Divide(ref FInt one, ref FInt other, out FInt dest) { dest.RawValue = (one.RawValue << SHIFT_AMOUNT) / (other.RawValue); }
public static void Multiply(ref FInt one, ref FInt other, out FInt dest) { dest.RawValue = (one.RawValue * other.RawValue) >> SHIFT_AMOUNT; }
public static FInt Abs(FInt F) { if (F < 0) return F.Inverse; else return F; }
public static FInt PIOver180F = PI / (FInt)180; //PI / 180 #endregion #region Sqrt 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"); else return k; }
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) { if (F1 >= 0) result = (PI - Atan(Abs(F1 / F2))); else result = (PI - Atan(Abs(F1 / F2))).Inverse; } else result = (F1 >= 0 ? PI : PI.Inverse) / new FInt(2, true); return result; }
public static FInt Tan(FInt i) { return Sin(i) / Cos(i); }
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(new FInt(145103 >> FInt.SHIFT_AMOUNT, false), F) - new FInt(599880 >> FInt.SHIFT_AMOUNT, false), F) + new FInt(1420468 >> FInt.SHIFT_AMOUNT, false), F) - new FInt(3592413 >> FInt.SHIFT_AMOUNT, false), F) + new FInt(26353447 >> FInt.SHIFT_AMOUNT, false); FInt f2 = PI / new FInt(2, true) - (Sqrt(FInt.OneF - F) * f1); return isNegative ? f2.Inverse : f2; }
private static FInt mul(FInt F1, FInt F2) { return F1 * F2; }
public static FInt Cos(FInt i) { return Sin(i + new FInt(6435, false)); }
private static FInt sin_lookup(FInt i, FInt j) { if (j > 0 && j < new FInt(10, false) && i < new FInt(90, false)) return new FInt(SIN_TABLE[i.RawValue], false) + ((new FInt(SIN_TABLE[i.RawValue + 1], false) - new FInt(SIN_TABLE[i.RawValue], false)) / new FInt(10, false)) * j; else return new FInt(SIN_TABLE[i.RawValue], false); }
public static FInt Sin(FInt i) { FInt j = (FInt)0; for (; i < 0; i += new FInt(25736, false)) ; if (i > new FInt(25736, false)) i %= new FInt(25736, false); FInt k = (i * new FInt(10, false)) / new FInt(714, false); if (i != 0 && i != new FInt(6434, false) && i != new FInt(12868, false) && i != new FInt(19302, false) && i != new FInt(25736, false)) j = (i * new FInt(100, false)) / new FInt(714, false) - k * new FInt(10, false); if (k <= new FInt(90, false)) return sin_lookup(k, j); if (k <= new FInt(180, false)) return sin_lookup(new FInt(180, false) - k, j); if (k <= new FInt(270, false)) return sin_lookup(k - new FInt(180, false), j).Inverse; else return sin_lookup(new FInt(360, false) - k, j).Inverse; }
public static FInt Sqrt(FInt f) { byte numberOfIterations = 8; if (f.RawValue > 0x64000) numberOfIterations = 12; if (f.RawValue > 0x3e8000) numberOfIterations = 16; return Sqrt(f, numberOfIterations); }
public PVector2(FInt x, FInt y) { X = x; Y = y; }
public static FInt Atan(FInt F) { return Asin(F / Sqrt(FInt.OneF + (F * F))); }
public static void Multiply(ref PVector2 v, ref FInt i, out PVector2 o) { FInt.Multiply(ref v.X, ref i, out o.X); FInt.Multiply(ref v.Y, ref i, out o.Y); }
public static void Sub(ref FInt one, ref FInt other, out FInt dest) { dest.RawValue = (one.RawValue - other.RawValue); }