Merge pull request #71496 from raulsntos/dotnet/sincos

C#: Implement `Mathf.SinCos`
This commit is contained in:
Rémi Verschelde 2023-01-16 22:13:46 +01:00 committed by GitHub
commit 5f7ac9fe10
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 73 additions and 48 deletions

View file

@ -816,26 +816,26 @@ namespace Godot
public Basis(Vector3 axis, real_t angle)
{
Vector3 axisSq = new Vector3(axis.x * axis.x, axis.y * axis.y, axis.z * axis.z);
real_t cosine = Mathf.Cos(angle);
Row0.x = axisSq.x + cosine * (1.0f - axisSq.x);
Row1.y = axisSq.y + cosine * (1.0f - axisSq.y);
Row2.z = axisSq.z + cosine * (1.0f - axisSq.z);
(real_t sin, real_t cos) = Mathf.SinCos(angle);
real_t sine = Mathf.Sin(angle);
real_t t = 1.0f - cosine;
Row0.x = axisSq.x + cos * (1.0f - axisSq.x);
Row1.y = axisSq.y + cos * (1.0f - axisSq.y);
Row2.z = axisSq.z + cos * (1.0f - axisSq.z);
real_t t = 1.0f - cos;
real_t xyzt = axis.x * axis.y * t;
real_t zyxs = axis.z * sine;
real_t zyxs = axis.z * sin;
Row0.y = xyzt - zyxs;
Row1.x = xyzt + zyxs;
xyzt = axis.x * axis.z * t;
zyxs = axis.y * sine;
zyxs = axis.y * sin;
Row0.z = xyzt + zyxs;
Row2.x = xyzt - zyxs;
xyzt = axis.y * axis.z * t;
zyxs = axis.x * sine;
zyxs = axis.x * sin;
Row1.z = xyzt - zyxs;
Row2.y = xyzt + zyxs;
}
@ -885,19 +885,29 @@ namespace Godot
/// <param name="order">The order to compose the Euler angles.</param>
public static Basis FromEuler(Vector3 euler, EulerOrder order = EulerOrder.Yxz)
{
real_t c, s;
(real_t sin, real_t cos) = Mathf.SinCos(euler.x);
Basis xmat = new Basis
(
new Vector3(1, 0, 0),
new Vector3(0, cos, sin),
new Vector3(0, -sin, cos)
);
c = Mathf.Cos(euler.x);
s = Mathf.Sin(euler.x);
Basis xmat = new Basis(new Vector3(1, 0, 0), new Vector3(0, c, s), new Vector3(0, -s, c));
(sin, cos) = Mathf.SinCos(euler.y);
Basis ymat = new Basis
(
new Vector3(cos, 0, -sin),
new Vector3(0, 1, 0),
new Vector3(sin, 0, cos)
);
c = Mathf.Cos(euler.y);
s = Mathf.Sin(euler.y);
Basis ymat = new Basis(new Vector3(c, 0, -s), new Vector3(0, 1, 0), new Vector3(s, 0, c));
c = Mathf.Cos(euler.z);
s = Mathf.Sin(euler.z);
Basis zmat = new Basis(new Vector3(c, s, 0), new Vector3(-s, c, 0), new Vector3(0, 0, 1));
(sin, cos) = Mathf.SinCos(euler.z);
Basis zmat = new Basis
(
new Vector3(cos, sin, 0),
new Vector3(-sin, cos, 0),
new Vector3(0, 0, 1)
);
switch (order)
{

View file

@ -82,6 +82,17 @@ namespace Godot
return (int)Math.Round(s);
}
/// <summary>
/// Returns the sine and cosine of angle <paramref name="s"/> in radians.
/// </summary>
/// <param name="s">The angle in radians.</param>
/// <returns>The sine and cosine of that angle.</returns>
public static (real_t Sin, real_t Cos) SinCos(real_t s)
{
(double sin, double cos) = Math.SinCos(s);
return ((real_t)sin, (real_t)cos);
}
/// <summary>
/// Returns <see langword="true"/> if <paramref name="a"/> and <paramref name="b"/> are approximately
/// equal to each other.

View file

@ -381,14 +381,14 @@ namespace Godot
}
real_t radians = Mathf.DegToRad(fovyDegrees / (real_t)2.0);
real_t deltaZ = zFar - zNear;
real_t sine = Mathf.Sin(radians);
(real_t sin, real_t cos) = Mathf.SinCos(radians);
if ((deltaZ == 0) || (sine == 0) || (aspect == 0))
if ((deltaZ == 0) || (sin == 0) || (aspect == 0))
{
return Zero;
}
real_t cotangent = Mathf.Cos(radians) / sine;
real_t cotangent = cos / sin;
Projection proj = Projection.Identity;

View file

@ -542,14 +542,13 @@ namespace Godot
}
else
{
real_t sinAngle = Mathf.Sin(angle * 0.5f);
real_t cosAngle = Mathf.Cos(angle * 0.5f);
real_t s = sinAngle / d;
(real_t sin, real_t cos) = Mathf.SinCos(angle * 0.5f);
real_t s = sin / d;
x = axis.x * s;
y = axis.y * s;
z = axis.z * s;
w = cosAngle;
w = cos;
}
}
@ -593,12 +592,9 @@ namespace Godot
// Conversion to quaternion as listed in https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770024290.pdf (page A-6)
// a3 is the angle of the first rotation, following the notation in this reference.
real_t cosA1 = Mathf.Cos(halfA1);
real_t sinA1 = Mathf.Sin(halfA1);
real_t cosA2 = Mathf.Cos(halfA2);
real_t sinA2 = Mathf.Sin(halfA2);
real_t cosA3 = Mathf.Cos(halfA3);
real_t sinA3 = Mathf.Sin(halfA3);
(real_t sinA1, real_t cosA1) = Mathf.SinCos(halfA1);
(real_t sinA2, real_t cosA2) = Mathf.SinCos(halfA2);
(real_t sinA3, real_t cosA3) = Mathf.SinCos(halfA3);
return new Quaternion(
(sinA1 * cosA2 * sinA3) + (cosA1 * sinA2 * cosA3),

View file

@ -195,8 +195,10 @@ namespace Godot
Vector2 s2 = transform.GetScale();
// Slerp rotation
var v1 = new Vector2(Mathf.Cos(r1), Mathf.Sin(r1));
var v2 = new Vector2(Mathf.Cos(r2), Mathf.Sin(r2));
(real_t sin1, real_t cos1) = Mathf.SinCos(r1);
(real_t sin2, real_t cos2) = Mathf.SinCos(r2);
var v1 = new Vector2(cos1, sin1);
var v2 = new Vector2(cos2, sin2);
real_t dot = v1.Dot(v2);
@ -213,7 +215,8 @@ namespace Godot
{
real_t angle = weight * Mathf.Acos(dot);
Vector2 v3 = (v2 - (v1 * dot)).Normalized();
v = (v1 * Mathf.Cos(angle)) + (v3 * Mathf.Sin(angle));
(real_t sine, real_t cos) = Mathf.SinCos(angle);
v = (v1 * sine) + (v3 * cos);
}
// Extract parameters
@ -434,8 +437,9 @@ namespace Godot
/// <param name="origin">The origin vector, or column index 2.</param>
public Transform2D(real_t rotation, Vector2 origin)
{
x.x = y.y = Mathf.Cos(rotation);
x.y = y.x = Mathf.Sin(rotation);
(real_t sin, real_t cos) = Mathf.SinCos(rotation);
x.x = y.y = cos;
x.y = y.x = sin;
y.x *= -1;
this.origin = origin;
}
@ -451,10 +455,12 @@ namespace Godot
/// <param name="origin">The origin vector, or column index 2.</param>
public Transform2D(real_t rotation, Vector2 scale, real_t skew, Vector2 origin)
{
x.x = Mathf.Cos(rotation) * scale.x;
y.y = Mathf.Cos(rotation + skew) * scale.y;
y.x = -Mathf.Sin(rotation + skew) * scale.y;
x.y = Mathf.Sin(rotation) * scale.x;
(real_t rotationSin, real_t rotationCos) = Mathf.SinCos(rotation);
(real_t rotationSkewSin, real_t rotationSkewCos) = Mathf.SinCos(rotation + skew);
x.x = rotationCos * scale.x;
y.y = rotationSkewCos * scale.y;
y.x = -rotationSkewSin * scale.y;
x.y = rotationSin * scale.x;
this.origin = origin;
}

View file

@ -539,11 +539,12 @@ namespace Godot
/// <returns>The rotated vector.</returns>
public readonly Vector2 Rotated(real_t angle)
{
real_t sine = Mathf.Sin(angle);
real_t cosi = Mathf.Cos(angle);
return new Vector2(
x * cosi - y * sine,
x * sine + y * cosi);
(real_t sin, real_t cos) = Mathf.SinCos(angle);
return new Vector2
(
x * cos - y * sin,
x * sin + y * cos
);
}
/// <summary>
@ -693,7 +694,8 @@ namespace Godot
/// <returns>The resulting vector.</returns>
public static Vector2 FromAngle(real_t angle)
{
return new Vector2(Mathf.Cos(angle), Mathf.Sin(angle));
(real_t sin, real_t cos) = Mathf.SinCos(angle);
return new Vector2(cos, sin);
}
/// <summary>