public static Accum MakeAccum(long val) { Accum k = new Accum(); k.longValue = val; return(k); }
public static Accum Sin(Accum x) { if (!tablesGenerated) { GenerateTables(); } long xVal = x.Value; while (xVal > PI_2.Value) { xVal -= PI_2.Value; } while (xVal < 0) { xVal += PI_2.Value; } long x1 = (long)(Math.Floor(((double)xVal / Accum.FracUnit) / (Math.PI * 2 / SineLUTSize))), //(Floor (xVal / (PI_2 / SineLUTSize))), x2 = x1 + 1; Accum y1 = SineLUT [x1], y2 = SineLUT [x2], y = y1 + (y2 - y1) * (x * new Accum(SineLUTSize) / PI_2 - new Accum(x1)); return(y1); }
/// <summary> /// Scales the Vector3k to unit length. /// </summary> public void Normalize() { Accum scale = Accum.One / this.Length; x *= scale; y *= scale; z *= scale; }
/// <summary> /// Rounds a number upwards to the next integer. (Towards positive infinity) /// </summary> /// <param name="x">The number to round.</param> /// <returns>Returns x rounded upwards to the next integer.</returns> public static Accum Ceil(Accum x) { return(Accum.MakeAccum( (x.Value < 0) ? (x.Value & unchecked ((long)0xFFFFFFFFFFFF0000)) : ((x.Value + (Accum.FracUnit - 1)) & unchecked ((long)0xFFFFFFFFFFFF0000)) )); }
public static Vector3k operator /(double val, Vector3k vec) { var valAccum = new Accum(val); vec.x /= valAccum; vec.y /= valAccum; vec.z /= valAccum; return(vec); }
public static Vector3k operator +(long val, Vector3k vec) { var valAccum = new Accum(val); vec.x += valAccum; vec.y += valAccum; vec.z += valAccum; return(vec); }
public static Vector3k operator -(int val, Vector3k vec) { var valAccum = new Accum(val); vec.x -= valAccum; vec.y -= valAccum; vec.z -= valAccum; return(vec); }
// Sin/Cos: pi*2: 411774; LUT size: 131072; // LUT generation public static void GenerateTables() { for (int i = 0; i < SineLUT.Length; i++) { SineLUT [i] = new Accum(Math.Sin((Math.PI * 2 / SineLUTSize) * i)); } tablesGenerated = true; }
// Multiplication public static Vector3k operator *(Vector3k vec, double val) { var valAccum = new Accum(val); vec.x *= valAccum; vec.y *= valAccum; vec.z *= valAccum; return(vec); }
/// <summary> /// Returns x to the nth potency /// </summary> /// <param name="x">A number</param> /// <param name="n">An exponent</param> public static Accum Pow(Accum x, int n) { Accum ret = x; for (; n > 0; n--) { ret.Value *= x.Value; } return(ret); }
// Square root /// <summary> /// Returns the square root of a number /// </summary> /// <param name="x">A number</param> public static Accum Sqrt(Accum x) { if (x == Accum.One) { return(new Accum(Accum.FracUnit)); } if (x <= Accum.Zero) { return(Accum.Zero); } long val = 150 * Accum.FracUnit, xVal = x.Value; for (int i = 0; i < 15; i++) { val = (val + Accum.SafeDivision(xVal, val)) >> 1; } return(Accum.MakeAccum(val)); }
public static Accum WrapAngle(Accum x) { const int val = 360 << 16; // Just to make sure it doesn't calculate 360 << 16 on every WrapAngle call... return(Accum.MakeAccum(x.Value % val)); }
/// <summary> /// Truncates a number, dropping the fractional part. /// </summary> /// <param name="x">The number to truncate</param> /// <returns>Returns x without the fractional part</returns> public static Accum Truncate(Accum x) { return(new Accum(x.Value & 0xFFFF0000)); }
public Vector3k(Accum newX, Accum newY, Accum newZ) { x = newX; y = newY; z = newZ; }
/// <summary> /// Rounds a number to the nearest integer. /// </summary> /// <param name="x">The number to round.</param> /// <returns>Returns x rounded to the nearest integer.</returns> public static Accum Round(Accum x) { return(new Accum((x.Value + (Accum.FracUnit / 2)) & 0xFFFF0000)); }
// Potentiation (?) /// <summary> /// Returns the square of a number /// </summary> /// <param name="x">A number</param> public static Accum Square(Accum x) { return(x * x); }
public Accum(Accum val) { longValue = val.longValue; }
/*public static Accum AtanDegrees (Accum x) { return DegreesToRadians (Atan (x)); } * public static Accum Atan2Degrees (Accum x, Accum y) { return DegreesToRadians (Atan2 (x, y); }*/ #endregion #region Basic math functions // Absolute /// <summary> /// Returns the absolute value of a number /// </summary> /// <param name="x">A number</param> public static Accum Abs(Accum val) { return(val.Value < 0 ? -val : val); }
public static Accum CosDegrees(Accum x) { return(Sin(DegreesToRadians(x) + PIOver2)); }
public static Accum SinDegrees(Accum x) { return(Sin(DegreesToRadians(x))); }
// Clamping /// <summary> /// Clamps a number between a minimum and a maximum. /// </summary> /// <param name="n">The number to clamp.</param> /// <param name="min">The minimum allowed value.</param> /// <param name="max">The maximum allowed value.</param> /// <returns>min, if n is lower than min; max, if n is higher than max; n otherwise.</returns> public static Accum Clamp(Accum n, Accum min, Accum max) { return(Accum.MakeAccum(Math.Max(Math.Min(n.Value, max.Value), min.Value))); }
/// <summary> /// Clamps a number between a minimum and a maximum. /// </summary> /// <param name="n">The number to clamp.</param> /// <param name="min">The minimum allowed value.</param> /// <param name="max">The maximum allowed value.</param> /// <returns>min, if n is lower than min; max, if n is higher than max; n otherwise.</returns> public static Accum ClampInt(Accum n, int min, int max) { return(Accum.MakeAccum(Math.Max(Math.Min(n.Value, max << 16), min << 16))); }
/// <summary> /// Convert radians to degrees. /// </summary> /// <param name="radians">An angle in radians.</param> /// <returns>The angle expressed in degrees.</returns> public static Accum RadiansToDegrees(Accum radians) { return(radians * radToDegAccum); }
/// <summary> /// Convert degrees to radians. /// </summary> /// <param name="degrees">An angle in degrees.</param> /// <returns>The angle expressed in radians.</returns> public static Accum DegreesToRadians(Accum degrees) { return(degrees * degToRadAccum); }
public static Accum Cos(Accum x) { return(Sin(x + PIOver2)); }
public Vertex(Accum x, Accum y, Accum z, Accum normal) : this(x, y, z) { Normal = normal; }
public static bool IsBetween(Accum x, Accum min, Accum max) { return(x >= min && x <= max); }
public Vertex(Accum x, Accum y, Accum z) { X = x; Y = y; Z = z; }