Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 111 additions & 3 deletions src/Spatial.Tests/Units/AngleTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,119 @@ public void EqualsWithTolerance()
Assert.AreEqual(false, one.Equals(two, Angle.FromRadians(0.1)));
}

[TestCase(0, 1)]
[TestCase(30, 0.86602540378443871)]
[TestCase(-30, 0.86602540378443871)]
[TestCase(45, 0.70710678118654757)]
[TestCase(-45, 0.70710678118654757)]
[TestCase(60, 0.5)]
[TestCase(-60, 0.5)]
[TestCase(90, 0)]
[TestCase(-90, 0)]
[TestCase(120, -0.5)]
[TestCase(-120, -0.5)]
[TestCase(180, -1)]
[TestCase(-180, -1)]
[TestCase(270, 0)]
public void CosineRoundTrip(double degrees, double cosine)
{
var angle = Angle.FromDegrees(degrees);
Assert.AreEqual(cosine, angle.Cos, 1e-15);

if (degrees >= 0 && degrees <= 180)
{
var recovered = Angle.Acos(cosine);
Assert.AreEqual(angle.Degrees, recovered.Degrees, 1e-6);
}
}

[Test]
public void AcosException()
{
Assert.Throws<ArgumentOutOfRangeException>(() => Angle.Acos(5));
}

[TestCase(0, 0)]
[TestCase(30, 0.5)]
[TestCase(-30, -0.5)]
[TestCase(45, 0.70710678118654757)]
[TestCase(-45, -0.70710678118654757)]
[TestCase(60, 0.86602540378443871)]
[TestCase(-60, -0.86602540378443871)]
[TestCase(90, 1)]
[TestCase(-90, -1)]
[TestCase(120, 0.86602540378443871)]
[TestCase(-120, -0.86602540378443871)]
[TestCase(180, 0)]
[TestCase(-180, 0)]
[TestCase(270, -1)]
public void SineWithRoundTrip(double degrees, double sine)
{
var angle = Angle.FromDegrees(degrees);
Assert.AreEqual(sine, angle.Sin, 1e-15);

if (degrees >= -90 && degrees <= 90)
{
var recovered = Angle.Asin(sine);
Assert.AreEqual(angle.Degrees, recovered.Degrees, 1e-6);
}
}

[Test]
public void AsinException()
{
Assert.Throws<ArgumentOutOfRangeException>(() => Angle.Asin(5));
}

[TestCase(0, 0)]
[TestCase(30, 0.57735026918962573)]
[TestCase(-30, -0.57735026918962573)]
[TestCase(45, 1)]
[TestCase(-45, -1)]
[TestCase(60, 1.7320508075688767)]
[TestCase(-60, -1.7320508075688767)]
[TestCase(120, -1.7320508075688783)]
[TestCase(-120, 1.7320508075688783)]
[TestCase(180, 0)]
[TestCase(-180, 0)]
public void TangentWithRoundTrip(double degrees, double tangent)
{
var angle = Angle.FromDegrees(degrees);
Assert.AreEqual(tangent, angle.Tan, 1e-15);

if (degrees >= -90 && degrees <= 90)
{
var recovered = Angle.Atan(tangent);
Assert.AreEqual(angle.Degrees, recovered.Degrees, 1e-6);
}
}

[TestCase(0, 1, 0)]
[TestCase(30, 1.7320508075688772935274463415059, 1)]
[TestCase(-30, 1.7320508075688772935274463415059, -1)]
[TestCase(45, 1, 1)]
[TestCase(-45, 1, -1)]
[TestCase(60, 1, 1.7320508075688772935274463415059)]
[TestCase(-60, 1, -1.7320508075688772935274463415059)]
[TestCase(90, 0, 1)]
[TestCase(-90, 0, -1)]
[TestCase(120, -1, 1.7320508075688772935274463415059)]
[TestCase(-120, -1, -1.7320508075688772935274463415059)]
[TestCase(150, -1.7320508075688772935274463415059, 1)]
[TestCase(-150, -1.7320508075688772935274463415059, -1)]
[TestCase(180, -1, 0)]
public void Atan2(double degrees, double x, double y)
{
var expected = Angle.FromDegrees(degrees);
var actual = Angle.Atan2(y, x);
Assert.AreEqual(expected.Degrees, actual.Degrees, 1e-10);
}

[TestCase(90, 1.5707963267948966)]
public void FromDegrees(double degrees, double expected)
{
Assert.AreEqual(expected, Angle.FromDegrees(degrees).Radians);
Assert.AreEqual(degrees, Angle.FromDegrees(degrees).Degrees, 1E-6);
Assert.AreEqual(degrees, Angle.FromDegrees(degrees).Degrees);
}

[TestCase(1, 1)]
Expand All @@ -122,10 +230,10 @@ public void FromRadians(double radians, double expected)
Assert.AreEqual(expected, Angle.FromRadians(radians).Radians);
}

[TestCase(20, 33, 49, 0.35890271998857842)]
[TestCase(20, 33, 49, 0.35890270667277291)]
public void FromSexagesimal(int degrees, int minutes, double seconds, double expected)
{
Assert.AreEqual(expected, Angle.FromSexagesimal(degrees, minutes, seconds).Radians, 1E-6);
Assert.AreEqual(expected, Angle.FromSexagesimal(degrees, minutes, seconds).Radians);
}

[TestCase("5 °", 5 * DegToRad)]
Expand Down
12 changes: 6 additions & 6 deletions src/Spatial/Euclidean/CoordinateSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -257,12 +257,12 @@ public static CoordinateSystem Rotation(Angle angle, Vector3D v)
public static CoordinateSystem Rotation(Angle yaw, Angle pitch, Angle roll)
{
var cs = new CoordinateSystem();
var cosY = Math.Cos(yaw.Radians);
var sinY = Math.Sin(yaw.Radians);
var cosP = Math.Cos(pitch.Radians);
var sinP = Math.Sin(pitch.Radians);
var cosR = Math.Cos(roll.Radians);
var sinR = Math.Sin(roll.Radians);
var cosY = yaw.Cos;
var sinY = yaw.Sin;
var cosP = pitch.Cos;
var sinP = pitch.Sin;
var cosR = roll.Cos;
var sinR = roll.Sin;

cs[0, 0] = cosY * cosP;
cs[1, 0] = sinY * cosP;
Expand Down
4 changes: 2 additions & 2 deletions src/Spatial/Euclidean/Matrix2D.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ public static class Matrix2D
/// <returns>A transform matrix</returns>
public static DenseMatrix Rotation(Angle rotation)
{
double c = Math.Cos(rotation.Radians);
double s = Math.Sin(rotation.Radians);
var c = rotation.Cos;
var s = rotation.Sin;
return Create(c, -s, s, c);
}

Expand Down
31 changes: 15 additions & 16 deletions src/Spatial/Euclidean/Matrix3D.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double;
using MathNet.Spatial.Units;
Expand All @@ -20,10 +19,10 @@ public static Matrix<double> RotationAroundXAxis(Angle angle)
var rotationMatrix = new DenseMatrix(3, 3)
{
[0, 0] = 1,
[1, 1] = Math.Cos(angle.Radians),
[1, 2] = -Math.Sin(angle.Radians),
[2, 1] = Math.Sin(angle.Radians),
[2, 2] = Math.Cos(angle.Radians)
[1, 1] = angle.Cos,
[1, 2] = -angle.Sin,
[2, 1] = angle.Sin,
[2, 2] = angle.Cos
};
return rotationMatrix;
}
Expand All @@ -37,11 +36,11 @@ public static Matrix<double> RotationAroundYAxis(Angle angle)
{
var rotationMatrix = new DenseMatrix(3, 3)
{
[0, 0] = Math.Cos(angle.Radians),
[0, 2] = Math.Sin(angle.Radians),
[0, 0] = angle.Cos,
[0, 2] = angle.Sin,
[1, 1] = 1,
[2, 0] = -Math.Sin(angle.Radians),
[2, 2] = Math.Cos(angle.Radians)
[2, 0] = -angle.Sin,
[2, 2] = angle.Cos
};
return rotationMatrix;
}
Expand All @@ -55,10 +54,10 @@ public static Matrix<double> RotationAroundZAxis(Angle angle)
{
var rotationMatrix = new DenseMatrix(3, 3)
{
[0, 0] = Math.Cos(angle.Radians),
[0, 1] = -Math.Sin(angle.Radians),
[1, 0] = Math.Sin(angle.Radians),
[1, 1] = Math.Cos(angle.Radians),
[0, 0] = angle.Cos,
[0, 1] = -angle.Sin,
[1, 0] = angle.Sin,
[1, 1] = angle.Cos,
[2, 2] = 1
};
return rotationMatrix;
Expand Down Expand Up @@ -123,9 +122,9 @@ public static Matrix<double> RotationAroundArbitraryVector(Direction aboutVector
var unitTensorProduct = aboutVector.GetUnitTensorProduct();
var crossProductMatrix = aboutVector.CrossProductMatrix;

var r1 = DenseMatrix.CreateIdentity(3).Multiply(Math.Cos(angle.Radians));
var r2 = crossProductMatrix.Multiply(Math.Sin(angle.Radians));
var r3 = unitTensorProduct.Multiply(1 - Math.Cos(angle.Radians));
var r1 = DenseMatrix.CreateIdentity(3).Multiply(angle.Cos);
var r2 = crossProductMatrix.Multiply(angle.Sin);
var r3 = unitTensorProduct.Multiply(1 - angle.Cos);
var totalR = r1.Add(r2).Add(r3);
return totalR;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Spatial/Euclidean/Point2D.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ public static Point2D FromPolar(double radius, Angle angle)
}

return new Point2D(
radius * Math.Cos(angle.Radians),
radius * Math.Sin(angle.Radians));
radius * angle.Cos,
radius * angle.Sin);
}

/// <summary>
Expand Down
25 changes: 12 additions & 13 deletions src/Spatial/Euclidean/Vector2D.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public Vector2D(double x, double y)
/// Gets the length of the vector
/// </summary>
[Pure]
public double Length => Math.Sqrt((X * X) + (Y * Y));
public double Length => Math.Sqrt(X * X + Y * Y);

/// <summary>
/// Gets a vector orthogonal to this
Expand Down Expand Up @@ -168,8 +168,8 @@ public static Vector2D FromPolar(double radius, Angle angle)
}

return new Vector2D(
radius * Math.Cos(angle.Radians),
radius * Math.Sin(angle.Radians));
radius * angle.Cos,
radius * angle.Sin);
}

/// <summary>
Expand Down Expand Up @@ -305,8 +305,7 @@ public bool IsPerpendicularTo(Vector2D other, double tolerance = 1e-10)
public bool IsPerpendicularTo(Vector2D other, Angle tolerance)
{
var angle = AngleTo(other);
const double Perpendicular = Math.PI / 2;
return Math.Abs(angle.Radians - Perpendicular) < tolerance.Radians;
return (angle - Angle.HalfPi).Abs() < tolerance;
}

/// <summary>
Expand Down Expand Up @@ -366,8 +365,8 @@ public Angle AngleTo(Vector2D other)
return Angle.FromRadians(
Math.Abs(
Math.Atan2(
(X * other.Y) - (other.X * Y),
(X * other.X) + (Y * other.Y))));
X * other.Y - other.X * Y,
X * other.X + Y * other.Y)));
}

/// <summary>
Expand All @@ -378,10 +377,10 @@ public Angle AngleTo(Vector2D other)
[Pure]
public Vector2D Rotate(Angle angle)
{
var cs = Math.Cos(angle.Radians);
var sn = Math.Sin(angle.Radians);
var x = (X * cs) - (Y * sn);
var y = (X * sn) + (Y * cs);
var cs = angle.Cos;
var sn = angle.Sin;
var x = X * cs - Y * sn;
var y = X * sn + Y * cs;
return new Vector2D(x, y);
}

Expand All @@ -393,7 +392,7 @@ public Vector2D Rotate(Angle angle)
[Pure]
public double DotProduct(Vector2D other)
{
return (X * other.X) + (Y * other.Y);
return X * other.X + Y * other.Y;
}

/// <summary>
Expand All @@ -408,7 +407,7 @@ public double CrossProduct(Vector2D other)
{
// Though the cross product is undefined in 2D space, this is a useful mathematical operation to
// determine angular direction and to compute the area of 2D shapes
return (X * other.Y) - (Y * other.X);
return X * other.Y - Y * other.X;
}

/// <summary>
Expand Down
38 changes: 19 additions & 19 deletions src/Spatial/Projective/Matrix3DHomogeneous.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,8 @@ public static Matrix3DHomogeneous CreateScale(double sx, double sy, double sz)
public static Matrix3DHomogeneous RotationAroundXAxis(Angle angle)
{
var result = new Matrix3DHomogeneous();
var sinAngle = Math.Sin(angle.Radians);
var cosAngle = Math.Cos(angle.Radians);
var sinAngle = angle.Sin;
var cosAngle = angle.Cos;
result.matrix[1, 1] = cosAngle;
result.matrix[1, 2] = -sinAngle;
result.matrix[2, 1] = sinAngle;
Expand All @@ -179,8 +179,8 @@ public static Matrix3DHomogeneous RotationAroundXAxis(Angle angle)
public static Matrix3DHomogeneous RotationAroundYAxis(Angle angle)
{
var result = new Matrix3DHomogeneous();
var sinAngle = Math.Sin(angle.Radians);
var cosAngle = Math.Cos(angle.Radians);
var sinAngle = angle.Sin;
var cosAngle = angle.Cos;
result.matrix[0, 0] = cosAngle;
result.matrix[0, 2] = sinAngle;
result.matrix[2, 0] = -sinAngle;
Expand All @@ -196,8 +196,8 @@ public static Matrix3DHomogeneous RotationAroundYAxis(Angle angle)
public static Matrix3DHomogeneous RotationAroundZAxis(Angle angle)
{
var result = new Matrix3DHomogeneous();
var sinAngle = Math.Sin(angle.Radians);
var cosAngle = Math.Cos(angle.Radians);
var sinAngle = angle.Sin;
var cosAngle = angle.Cos;
result.matrix[0, 0] = cosAngle;
result.matrix[0, 1] = -sinAngle;
result.matrix[1, 0] = sinAngle;
Expand Down Expand Up @@ -281,10 +281,10 @@ public static Matrix3DHomogeneous TopView()
public static Matrix3DHomogeneous Axonometric(Angle alpha, Angle beta)
{
var result = new Matrix3DHomogeneous();
var sna = Math.Sin(alpha.Radians);
var cosAlpha = Math.Cos(alpha.Radians);
var sinBeta = Math.Sin(beta.Radians);
var cosBeta = Math.Cos(beta.Radians);
var sna = alpha.Sin;
var cosAlpha = alpha.Cos;
var sinBeta = beta.Sin;
var cosBeta = beta.Cos;
result.matrix[0, 0] = cosBeta;
result.matrix[0, 2] = sinBeta;
result.matrix[1, 0] = sna * sinBeta;
Expand All @@ -303,9 +303,9 @@ public static Matrix3DHomogeneous Axonometric(Angle alpha, Angle beta)
public static Matrix3DHomogeneous Oblique(Angle alpha, Angle theta)
{
var result = new Matrix3DHomogeneous();
var tanAlpha = Math.Tan(alpha.Radians);
var sinTheta = Math.Sin(theta.Radians);
var cosTheta = Math.Cos(theta.Radians);
var tanAlpha = alpha.Tan;
var sinTheta = theta.Sin;
var cosTheta = theta.Cos;
result.matrix[0, 2] = -cosTheta / tanAlpha;
result.matrix[1, 2] = -sinTheta / tanAlpha;
result.matrix[2, 2] = 0;
Expand All @@ -323,12 +323,12 @@ public static Matrix3DHomogeneous Euler(Angle alpha, Angle beta, Angle gamma)
{
var result = new Matrix3DHomogeneous();

var sinAlpha = Math.Sin(alpha.Radians);
var cosAlpha = Math.Cos(alpha.Radians);
var sinBeta = Math.Sin(beta.Radians);
var cosBeta = Math.Cos(beta.Radians);
var sinGamma = Math.Sin(gamma.Radians);
var cosGamma = Math.Cos(gamma.Radians);
var sinAlpha = alpha.Sin;
var cosAlpha = alpha.Cos;
var sinBeta = beta.Sin;
var cosBeta = beta.Cos;
var sinGamma = gamma.Sin;
var cosGamma = gamma.Cos;

result.matrix[0, 0] = (cosAlpha * cosGamma) - (sinAlpha * sinBeta * sinGamma);
result.matrix[0, 1] = -sinBeta * sinGamma;
Expand Down
Loading