[Mono] Approximate equality

This commit is contained in:
Aaron Franke 2019-04-01 18:13:38 -04:00
parent 7f7d97f536
commit c577ec6ae4
No known key found for this signature in database
GPG Key ID: 40A1750B977E56BF
7 changed files with 53 additions and 34 deletions

View File

@ -168,7 +168,7 @@ namespace Godot
int max = Mathf.Max(color.r8, Mathf.Max(color.g8, color.b8)); int max = Mathf.Max(color.r8, Mathf.Max(color.g8, color.b8));
int min = Mathf.Min(color.r8, Mathf.Min(color.g8, color.b8)); int min = Mathf.Min(color.r8, Mathf.Min(color.g8, color.b8));
float delta = max - min; int delta = max - min;
if (delta == 0) if (delta == 0)
{ {
@ -591,11 +591,11 @@ namespace Godot
public static bool operator <(Color left, Color right) public static bool operator <(Color left, Color right)
{ {
if (left.r == right.r) if (Mathf.IsEqualApprox(left.r, right.r))
{ {
if (left.g == right.g) if (Mathf.IsEqualApprox(left.g, right.g))
{ {
if (left.b == right.b) if (Mathf.IsEqualApprox(left.b, right.b))
return left.a < right.a; return left.a < right.a;
return left.b < right.b; return left.b < right.b;
} }
@ -608,11 +608,11 @@ namespace Godot
public static bool operator >(Color left, Color right) public static bool operator >(Color left, Color right)
{ {
if (left.r == right.r) if (Mathf.IsEqualApprox(left.r, right.r))
{ {
if (left.g == right.g) if (Mathf.IsEqualApprox(left.g, right.g))
{ {
if (left.b == right.b) if (Mathf.IsEqualApprox(left.b, right.b))
return left.a > right.a; return left.a > right.a;
return left.b > right.b; return left.b > right.b;
} }
@ -635,7 +635,7 @@ namespace Godot
public bool Equals(Color other) public bool Equals(Color other)
{ {
return r == other.r && g == other.g && b == other.b && a == other.a; return Mathf.IsEqualApprox(r, other.r) && Mathf.IsEqualApprox(g, other.g) && Mathf.IsEqualApprox(b, other.b) && Mathf.IsEqualApprox(a, other.a);
} }
public override int GetHashCode() public override int GetHashCode()

View File

@ -143,6 +143,15 @@ namespace Godot
return (weight - from) / (to - from); return (weight - from) / (to - from);
} }
public static bool IsEqualApprox(real_t a, real_t b)
{
real_t tolerance = Epsilon * Abs(a);
if (tolerance < Epsilon) {
tolerance = Epsilon;
}
return Abs(a - b) < tolerance;
}
public static bool IsInf(real_t s) public static bool IsInf(real_t s)
{ {
return real_t.IsInfinity(s); return real_t.IsInfinity(s);
@ -153,6 +162,11 @@ namespace Godot
return real_t.IsNaN(s); return real_t.IsNaN(s);
} }
public static bool IsZeroApprox(real_t s)
{
return Abs(s) < Epsilon;
}
public static real_t Lerp(real_t from, real_t to, real_t weight) public static real_t Lerp(real_t from, real_t to, real_t weight)
{ {
return from + (to - from) * weight; return from + (to - from) * weight;

View File

@ -36,9 +36,9 @@ namespace Godot
return (int)Math.Round(s); return (int)Math.Round(s);
} }
public static bool IsEqualApprox(real_t a, real_t b, real_t ratio = Mathf.Epsilon) public static bool IsEqualApprox(real_t a, real_t b, real_t tolerance)
{ {
return Abs(a - b) < ratio; return Abs(a - b) < tolerance;
} }
} }
} }

View File

@ -200,7 +200,7 @@ namespace Godot
public bool Equals(Plane other) public bool Equals(Plane other)
{ {
return _normal == other._normal && D == other.D; return _normal == other._normal && Mathf.IsEqualApprox(D, other.D);
} }
public override int GetHashCode() public override int GetHashCode()

View File

@ -358,7 +358,7 @@ namespace Godot
public bool Equals(Quat other) public bool Equals(Quat other)
{ {
return x == other.x && y == other.y && z == other.z && w == other.w; return Mathf.IsEqualApprox(x, other.x) && Mathf.IsEqualApprox(y, other.y) && Mathf.IsEqualApprox(z, other.z) && Mathf.IsEqualApprox(w, other.w);
} }
public override int GetHashCode() public override int GetHashCode()

View File

@ -52,11 +52,15 @@ namespace Godot
internal void Normalize() internal void Normalize()
{ {
real_t length = x * x + y * y; real_t lengthsq = LengthSquared();
if (length != 0f) if (lengthsq == 0)
{ {
length = Mathf.Sqrt(length); x = y = 0f;
}
else
{
real_t length = Mathf.Sqrt(lengthsq);
x /= length; x /= length;
y /= length; y /= length;
} }
@ -184,9 +188,9 @@ namespace Godot
public Vector2 Normalized() public Vector2 Normalized()
{ {
var result = this; var v = this;
result.Normalize(); v.Normalize();
return result; return v;
} }
public Vector2 Project(Vector2 onNormal) public Vector2 Project(Vector2 onNormal)
@ -343,7 +347,7 @@ namespace Godot
public static bool operator <(Vector2 left, Vector2 right) public static bool operator <(Vector2 left, Vector2 right)
{ {
if (left.x.Equals(right.x)) if (Mathf.IsEqualApprox(left.x, right.x))
{ {
return left.y < right.y; return left.y < right.y;
} }
@ -353,7 +357,7 @@ namespace Godot
public static bool operator >(Vector2 left, Vector2 right) public static bool operator >(Vector2 left, Vector2 right)
{ {
if (left.x.Equals(right.x)) if (Mathf.IsEqualApprox(left.x, right.x))
{ {
return left.y > right.y; return left.y > right.y;
} }
@ -363,7 +367,7 @@ namespace Godot
public static bool operator <=(Vector2 left, Vector2 right) public static bool operator <=(Vector2 left, Vector2 right)
{ {
if (left.x.Equals(right.x)) if (Mathf.IsEqualApprox(left.x, right.x))
{ {
return left.y <= right.y; return left.y <= right.y;
} }
@ -373,7 +377,7 @@ namespace Godot
public static bool operator >=(Vector2 left, Vector2 right) public static bool operator >=(Vector2 left, Vector2 right)
{ {
if (left.x.Equals(right.x)) if (Mathf.IsEqualApprox(left.x, right.x))
{ {
return left.y >= right.y; return left.y >= right.y;
} }
@ -393,7 +397,7 @@ namespace Godot
public bool Equals(Vector2 other) public bool Equals(Vector2 other)
{ {
return x == other.x && y == other.y; return Mathf.IsEqualApprox(x, other.x) && Mathf.IsEqualApprox(y, other.y);
} }
public override int GetHashCode() public override int GetHashCode()

View File

@ -65,14 +65,15 @@ namespace Godot
internal void Normalize() internal void Normalize()
{ {
real_t length = Length(); real_t lengthsq = LengthSquared();
if (length == 0f) if (lengthsq == 0)
{ {
x = y = z = 0f; x = y = z = 0f;
} }
else else
{ {
real_t length = Mathf.Sqrt(lengthsq);
x /= length; x /= length;
y /= length; y /= length;
z /= length; z /= length;
@ -397,9 +398,9 @@ namespace Godot
public static bool operator <(Vector3 left, Vector3 right) public static bool operator <(Vector3 left, Vector3 right)
{ {
if (left.x == right.x) if (Mathf.IsEqualApprox(left.x, right.x))
{ {
if (left.y == right.y) if (Mathf.IsEqualApprox(left.y, right.y))
return left.z < right.z; return left.z < right.z;
return left.y < right.y; return left.y < right.y;
} }
@ -409,9 +410,9 @@ namespace Godot
public static bool operator >(Vector3 left, Vector3 right) public static bool operator >(Vector3 left, Vector3 right)
{ {
if (left.x == right.x) if (Mathf.IsEqualApprox(left.x, right.x))
{ {
if (left.y == right.y) if (Mathf.IsEqualApprox(left.y, right.y))
return left.z > right.z; return left.z > right.z;
return left.y > right.y; return left.y > right.y;
} }
@ -421,9 +422,9 @@ namespace Godot
public static bool operator <=(Vector3 left, Vector3 right) public static bool operator <=(Vector3 left, Vector3 right)
{ {
if (left.x == right.x) if (Mathf.IsEqualApprox(left.x, right.x))
{ {
if (left.y == right.y) if (Mathf.IsEqualApprox(left.y, right.y))
return left.z <= right.z; return left.z <= right.z;
return left.y < right.y; return left.y < right.y;
} }
@ -433,9 +434,9 @@ namespace Godot
public static bool operator >=(Vector3 left, Vector3 right) public static bool operator >=(Vector3 left, Vector3 right)
{ {
if (left.x == right.x) if (Mathf.IsEqualApprox(left.x, right.x))
{ {
if (left.y == right.y) if (Mathf.IsEqualApprox(left.y, right.y))
return left.z >= right.z; return left.z >= right.z;
return left.y > right.y; return left.y > right.y;
} }
@ -455,7 +456,7 @@ namespace Godot
public bool Equals(Vector3 other) public bool Equals(Vector3 other)
{ {
return x == other.x && y == other.y && z == other.z; return Mathf.IsEqualApprox(x, other.x) && Mathf.IsEqualApprox(y, other.y) && Mathf.IsEqualApprox(z, other.z);
} }
public override int GetHashCode() public override int GetHashCode()