Add Exts.ISqrt to avoid fp sqrt calculations.
This commit is contained in:
@@ -47,7 +47,7 @@ namespace OpenRA
|
||||
public CVec Sign() { return new CVec(Math.Sign(X), Math.Sign(Y)); }
|
||||
public CVec Abs() { return new CVec(Math.Abs(X), Math.Abs(Y)); }
|
||||
public int LengthSquared { get { return X * X + Y * Y; } }
|
||||
public int Length { get { return (int)Math.Sqrt(LengthSquared); } }
|
||||
public int Length { get { return Exts.ISqrt(LengthSquared); } }
|
||||
|
||||
public float2 ToFloat2() { return new float2(X, Y); }
|
||||
public int2 ToInt2() { return new int2(X, Y); }
|
||||
|
||||
@@ -202,6 +202,91 @@ namespace OpenRA
|
||||
|
||||
public static Size NextPowerOf2(this Size s) { return new Size(NextPowerOf2(s.Width), NextPowerOf2(s.Height)); }
|
||||
|
||||
public enum ISqrtRoundMode { Floor, Nearest, Ceiling }
|
||||
public static int ISqrt(int number, ISqrtRoundMode round = ISqrtRoundMode.Floor)
|
||||
{
|
||||
if (number < 0)
|
||||
throw new InvalidOperationException("Attempted to calculate the square root of a negative integer: {0}".F(number));
|
||||
|
||||
return (int)ISqrt((uint)number, round);
|
||||
}
|
||||
|
||||
public static uint ISqrt(uint number, ISqrtRoundMode round = ISqrtRoundMode.Floor)
|
||||
{
|
||||
var divisor = 1U << 30;
|
||||
|
||||
var root = 0U;
|
||||
var remainder = number;
|
||||
|
||||
// Find the highest term in the divisor
|
||||
while (divisor > number)
|
||||
divisor >>= 2;
|
||||
|
||||
// Evaluate the root, two bits at a time
|
||||
while (divisor != 0)
|
||||
{
|
||||
if (root + divisor <= remainder)
|
||||
{
|
||||
remainder -= root + divisor;
|
||||
root += 2 * divisor;
|
||||
}
|
||||
|
||||
root >>= 1;
|
||||
divisor >>= 2;
|
||||
}
|
||||
|
||||
// Adjust for other rounding modes
|
||||
if (round == ISqrtRoundMode.Nearest && remainder > root)
|
||||
root += 1;
|
||||
|
||||
else if (round == ISqrtRoundMode.Ceiling && root * root < number)
|
||||
root += 1;
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
public static long ISqrt(long number, ISqrtRoundMode round = ISqrtRoundMode.Floor)
|
||||
{
|
||||
if (number < 0)
|
||||
throw new InvalidOperationException("Attempted to calculate the square root of a negative integer: {0}".F(number));
|
||||
|
||||
return (long)ISqrt((ulong)number, round);
|
||||
}
|
||||
|
||||
public static ulong ISqrt(ulong number, ISqrtRoundMode round = ISqrtRoundMode.Floor)
|
||||
{
|
||||
var divisor = 1UL << 62;
|
||||
|
||||
var root = 0UL;
|
||||
var remainder = number;
|
||||
|
||||
// Find the highest term in the divisor
|
||||
while (divisor > number)
|
||||
divisor >>= 2;
|
||||
|
||||
// Evaluate the root, two bits at a time
|
||||
while (divisor != 0)
|
||||
{
|
||||
if (root + divisor <= remainder)
|
||||
{
|
||||
remainder -= root + divisor;
|
||||
root += 2 * divisor;
|
||||
}
|
||||
|
||||
root >>= 1;
|
||||
divisor >>= 2;
|
||||
}
|
||||
|
||||
// Adjust for other rounding modes
|
||||
if (round == ISqrtRoundMode.Nearest && remainder > root)
|
||||
root += 1;
|
||||
|
||||
else if (round == ISqrtRoundMode.Ceiling && root * root < number)
|
||||
root += 1;
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
public static string JoinWith<T>(this IEnumerable<T> ts, string j)
|
||||
{
|
||||
return string.Join(j, ts);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
namespace OpenRA.Graphics
|
||||
@@ -98,7 +99,7 @@ namespace OpenRA.Graphics
|
||||
var yc = (r.Bottom + r.Top) / 2;
|
||||
for (var y = r.Top; y <= r.Bottom; y++)
|
||||
{
|
||||
var dx = a * System.Convert.ToSingle(System.Math.Sqrt(1 - (y - yc) * (y - yc) / b / b));
|
||||
var dx = a * (float)(Math.Sqrt(1 - (y - yc) * (y - yc) / b / b));
|
||||
DrawLine(new float2(xc - dx, y), new float2(xc + dx, y), color, color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -623,7 +623,7 @@ namespace OpenRA
|
||||
for (var j = -max; j <= max; j++)
|
||||
for (var i = -max; i <= max; i++)
|
||||
if (max * max >= i * i + j * j)
|
||||
ts [(int)Math.Ceiling(Math.Sqrt(i * i + j * j))].Add(new CVec(i, j));
|
||||
ts [Exts.ISqrt(i * i + j * j, Exts.ISqrtRoundMode.Ceiling)].Add(new CVec(i, j));
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace OpenRA
|
||||
public int2 Sign() { return new int2(Math.Sign(X), Math.Sign(Y)); }
|
||||
public int2 Abs() { return new int2(Math.Abs(X), Math.Abs(Y)); }
|
||||
public int LengthSquared { get { return X * X + Y * Y; } }
|
||||
public int Length { get { return (int)Math.Sqrt(LengthSquared); } }
|
||||
public int Length { get { return Exts.ISqrt(LengthSquared); } }
|
||||
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); }
|
||||
|
||||
public static int2 Max(int2 a, int2 b) { return new int2(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
|
||||
|
||||
@@ -37,9 +37,9 @@ namespace OpenRA
|
||||
|
||||
public static int Dot(WVec a, WVec b) { return a.X * b.X + a.Y * b.Y + a.Z * b.Z; }
|
||||
public long LengthSquared { get { return (long)X * X + (long)Y * Y + (long)Z * Z; } }
|
||||
public int Length { get { return (int)Math.Sqrt(LengthSquared); } }
|
||||
public int Length { get { return (int)Exts.ISqrt(LengthSquared); } }
|
||||
public long HorizontalLengthSquared { get { return (long)X * X + (long)Y * Y; } }
|
||||
public int HorizontalLength { get { return (int)Math.Sqrt(HorizontalLengthSquared); } }
|
||||
public int HorizontalLength { get { return (int)Exts.ISqrt(HorizontalLengthSquared); } }
|
||||
|
||||
public WVec Rotate(WRot rot)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user