Last active
July 5, 2018 11:08
-
-
Save a3geek/1e169783f6951ad0c2300ea224fede19 to your computer and use it in GitHub Desktop.
Complex structure for Unity C#
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System; | |
using System.Globalization; | |
namespace Gists | |
{ | |
[Serializable] | |
public struct Complex | |
{ | |
public static readonly Complex Zero = new Complex(0f, 0f); | |
public static readonly Complex One = new Complex(1f, 0f); | |
public static readonly Complex ImaginaryOne = new Complex(0f, 1f); | |
public float Real | |
{ | |
get { return this.real; } | |
} | |
public float Imaginary | |
{ | |
get { return this.imaginary; } | |
} | |
public float Magnitude | |
{ | |
get { return Abs(this); } | |
} | |
public float SqrMagnitude | |
{ | |
get { return SqrAbs(this); } | |
} | |
public float Phase | |
{ | |
get { return Mathf.Atan2(this.imaginary, this.real); } | |
} | |
public Vector2 Vec2 | |
{ | |
get { return new Vector2(this.real, this.imaginary); } | |
} | |
[SerializeField] | |
private float real; | |
[SerializeField] | |
private float imaginary; | |
public Complex(Vector2 vec2) : this(vec2.x, vec2.y) { } | |
public Complex(Complex other) : this(other.real, other.imaginary) { } | |
public Complex(float real, float imaginary) | |
{ | |
this.real = real; | |
this.imaginary = imaginary; | |
} | |
public override string ToString() | |
{ | |
return String.Format(CultureInfo.CurrentCulture, "({0}, {1})", this.real, this.imaginary); | |
} | |
#region "Static Methods" | |
public static Complex FromPolarCoordinates(float magnitude, float phase) | |
{ | |
return new Complex(magnitude * Mathf.Cos(phase), magnitude * Mathf.Sin(phase)); | |
} | |
public static Complex Conjugate(Complex complex) | |
{ | |
return new Complex(complex.real, -complex.imaginary); | |
} | |
public static Complex Negate(Complex complex) | |
{ | |
return -complex; | |
} | |
public static Complex Add(Complex left, Complex right) | |
{ | |
return left + right; | |
} | |
public static Complex Subtract(Complex left, Complex right) | |
{ | |
return left - right; | |
} | |
public static Complex Multiply(Complex left, Complex right) | |
{ | |
return left * right; | |
} | |
public static Complex Multiply(Complex left, float right) | |
{ | |
return new Complex(left.real * right, left.imaginary * right); | |
} | |
public static Complex Divide(Complex dividend, Complex divisor) | |
{ | |
return dividend / divisor; | |
} | |
public static Complex Divide(Complex dividend, float divisor) | |
{ | |
return new Complex(dividend.real / divisor, dividend.imaginary / divisor); | |
} | |
public static Complex Sqrt(Complex complex) | |
{ | |
return FromPolarCoordinates(Mathf.Sqrt(complex.Magnitude), complex.Phase / 2f); | |
} | |
public static float SqrAbs(Complex complex) | |
{ | |
if(float.IsInfinity(complex.real) == true || float.IsInfinity(complex.imaginary) == true) | |
{ | |
return float.PositiveInfinity; | |
} | |
return complex.real * complex.real + complex.imaginary * complex.imaginary; | |
} | |
public static float Abs(Complex complex) | |
{ | |
if(float.IsInfinity(complex.real) == true || float.IsInfinity(complex.imaginary) == true) | |
{ | |
return float.PositiveInfinity; | |
} | |
var r = Mathf.Abs(complex.real); | |
var i = Mathf.Abs(complex.imaginary); | |
if(r > i) | |
{ | |
var d = i / r; | |
return r * Mathf.Sqrt(1f + d * d); | |
} | |
else if(Math.Abs(i) < Mathf.Epsilon) | |
{ | |
return r; | |
} | |
else | |
{ | |
var d = r / i; | |
return i * Mathf.Sqrt(1f + d * d); | |
} | |
} | |
#endregion | |
#region "Operators" | |
public static Complex operator -(Complex complex) | |
{ | |
return new Complex(-complex.real, -complex.imaginary); | |
} | |
public static Complex operator +(Complex left, Complex right) | |
{ | |
return new Complex(left.real + right.real, left.imaginary + right.imaginary); | |
} | |
public static Complex operator -(Complex left, Complex right) | |
{ | |
return new Complex(left.real - right.real, left.imaginary - right.imaginary); | |
} | |
public static Complex operator *(Complex left, Complex right) | |
{ | |
// (a + bi) * (c + di) = (ac - bd) + (bc + ad)i | |
var real = (left.real * right.real) - (left.imaginary * right.imaginary); | |
var imaginary = (left.imaginary * right.real) + (left.real * right.imaginary); | |
return new Complex(real, imaginary); | |
} | |
public static Complex operator /(Complex left, Complex right) | |
{ | |
var denominator = right.SqrMagnitude; | |
if(Math.Abs(denominator) < Mathf.Epsilon || float.IsInfinity(denominator) == true) | |
{ | |
return Zero; | |
} | |
return new Complex( | |
(left.real * right.real + left.imaginary * right.imaginary) / denominator, | |
(right.real * left.imaginary - left.real * right.imaginary) / denominator | |
); | |
} | |
#endregion | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment