diff --git a/OpenRA.FileFormats/WAngle.cs b/OpenRA.FileFormats/WAngle.cs index 80dd98aa96..dcc8bcc7fa 100644 --- a/OpenRA.FileFormats/WAngle.cs +++ b/OpenRA.FileFormats/WAngle.cs @@ -67,6 +67,41 @@ namespace OpenRA return new WAngle(Angle - 512).Tan(); } + public static WAngle ArcTan(int y, int x) + { + if (y == 0) + return new WAngle(x >= 0 ? 0 : 512); + + if (x == 0) + return new WAngle(Math.Sign(y)*256); + + var ay = Math.Abs(y); + var ax = Math.Abs(x); + + // Find the closest angle that satisfies y = x*tan(theta) + var bestVal = int.MaxValue; + var bestAngle = 0; + for (var i = 0; i < 256; i++) + { + var val = Math.Abs(1024*ay - ax*TanTable[i]); + if (val < bestVal) + { + bestVal = val; + bestAngle = i; + } + } + + // Calculate quadrant + if (x < 0 && y > 0) + bestAngle = 512 - bestAngle; + else if (x < 0 && y < 0) + bestAngle = 512 + bestAngle; + else if (x > 0 && y < 0) + bestAngle = 1024 - bestAngle; + + return new WAngle(bestAngle); + } + // Must not be used outside rendering code public float RendererRadians() { return (float)(Angle * Math.PI / 512f); } public float RendererDegrees() { return Angle * 0.3515625f; }