diff --git a/NetFabric.Angle.UnitTests/AngleDegreesTests.cs b/NetFabric.Angle.UnitTests/AngleDegreesTests.cs index 9a92b65..1b0257d 100644 --- a/NetFabric.Angle.UnitTests/AngleDegreesTests.cs +++ b/NetFabric.Angle.UnitTests/AngleDegreesTests.cs @@ -1,5 +1,6 @@ using FluentAssertions; using System; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Runtime.Serialization.Formatters.Binary; @@ -11,96 +12,6 @@ public class AngleDegreesTests { static readonly AngleDegrees AcuteAngle = AngleDegrees.Right / 2.0; - public static TheoryData AngleDegreesMinutesData = new TheoryData - { - { 40, 0.0, Angle.FromDegrees(40) }, - { -40, 0.0, Angle.FromDegrees(-40) }, - { 40, 30.0, Angle.FromDegrees(40.5) }, - { -40, 30.0, Angle.FromDegrees(-40.5) }, - }; - - [Theory] - [MemberData(nameof(AngleDegreesMinutesData))] - public void ToDegrees_When_AngleMinutes_Should_Succeed(int degrees, double minutes, AngleDegrees expected) - { - // arrange - - // act - var angle = Angle.FromDegrees(degrees, minutes); - - // assert - angle.Degrees.Should().BeApproximately(expected.Degrees, 0.0001); - } - - public static TheoryData AngleDegreesMinutesSecondsData = new TheoryData - { - { 40, 0, 0.0, Angle.FromDegrees(40) }, - { -40, 0, 0.0, Angle.FromDegrees(-40) }, - { 40, 30, 30.0, Angle.FromDegrees(40.50833) }, - { -40, 30, 30.0, Angle.FromDegrees(-40.50833) }, - }; - - [Theory] - [MemberData(nameof(AngleDegreesMinutesSecondsData))] - public void ToDegrees_When_AngleMinutesSeconds_Should_Succeed(int degrees, int minutes, double seconds, AngleDegrees expected) - { - // arrange - - // act - var angle = Angle.FromDegrees(degrees, minutes, seconds); - - // assert - angle.Degrees.Should().BeApproximately(expected.Degrees, 0.0001); - } - - public static TheoryData AngleRadiansData = new TheoryData - { - { -AngleRadians.Full, -AngleDegrees.Full }, - { -AngleRadians.Straight, -AngleDegrees.Straight }, - { -AngleRadians.Right, -AngleDegrees.Right }, - { AngleRadians.Zero, AngleDegrees.Zero }, - { AngleRadians.Right, AngleDegrees.Right }, - { AngleRadians.Straight, AngleDegrees.Straight }, - { AngleRadians.Full, AngleDegrees.Full }, - }; - - [Theory] - [MemberData(nameof(AngleRadiansData))] - public void ToDegrees_When_AngleRadians_Should_Succeed(AngleRadians value, AngleDegrees expected) - { - // arrange - - // act - var angle = Angle.ToDegrees(value); - - // assert - angle.Should().BeOfType().And.Be(expected); - } - - public static TheoryData AngleGradiansData = new TheoryData - { - { -AngleGradians.Full, -AngleDegrees.Full }, - { -AngleGradians.Straight, -AngleDegrees.Straight }, - { -AngleGradians.Right, -AngleDegrees.Right }, - { AngleGradians.Zero, AngleDegrees.Zero }, - { AngleGradians.Right, AngleDegrees.Right }, - { AngleGradians.Straight, AngleDegrees.Straight }, - { AngleGradians.Full, AngleDegrees.Full }, - }; - - [Theory] - [MemberData(nameof(AngleGradiansData))] - public void ToDegrees_When_AngleGradians_Should_Succeed(AngleGradians value, AngleDegrees expected) - { - // arrange - - // act - var angle = Angle.ToDegrees(value); - - // assert - angle.Should().BeOfType().And.Be(expected); - } - public static TheoryData SerializableData = new TheoryData { -AngleDegrees.Full, @@ -178,6 +89,7 @@ public void Serializable_Should_Succeed(AngleDegrees angle) [Theory] [MemberData(nameof(CompareInvalidData))] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void EqualsObject_Should_Succeed(AngleDegrees left, object right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -191,6 +103,7 @@ public void EqualsObject_Should_Succeed(AngleDegrees left, object right, bool le [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void Equals_Should_Succeed(AngleDegrees left, AngleDegrees right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -204,6 +117,7 @@ public void Equals_Should_Succeed(AngleDegrees left, AngleDegrees right, bool le [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void GetHashCode_Should_Succeed(AngleDegrees left, AngleDegrees right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -220,6 +134,7 @@ public void GetHashCode_Should_Succeed(AngleDegrees left, AngleDegrees right, bo [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void OperatorEquality_Should_Succeed(AngleDegrees left, AngleDegrees right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -233,6 +148,7 @@ public void OperatorEquality_Should_Succeed(AngleDegrees left, AngleDegrees righ [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void OperatorInequality_Should_Succeed(AngleDegrees left, AngleDegrees right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -246,6 +162,7 @@ public void OperatorInequality_Should_Succeed(AngleDegrees left, AngleDegrees ri [Theory] [MemberData(nameof(CompareInvalidData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void CompareTo_When_InvalidData_Should_Thrown(AngleDegrees angle, object obj, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -261,6 +178,7 @@ public void CompareTo_When_InvalidData_Should_Thrown(AngleDegrees angle, object [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void CompareTo_Should_Succeed(AngleDegrees left, AngleDegrees right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -279,6 +197,7 @@ public void CompareTo_Should_Succeed(AngleDegrees left, AngleDegrees right, bool [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void Compare_Should_Succeed(AngleDegrees left, AngleDegrees right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -297,6 +216,7 @@ public void Compare_Should_Succeed(AngleDegrees left, AngleDegrees right, bool l [Theory] [MemberData(nameof(CompareReducedData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void CompareReduced_Should_Succeed(AngleDegrees left, AngleDegrees right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -315,6 +235,7 @@ public void CompareReduced_Should_Succeed(AngleDegrees left, AngleDegrees right, [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void LessThan_Should_Succeed(AngleDegrees left, AngleDegrees right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -328,6 +249,7 @@ public void LessThan_Should_Succeed(AngleDegrees left, AngleDegrees right, bool [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void LessThanOrEqual_Should_Succeed(AngleDegrees left, AngleDegrees right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -341,6 +263,7 @@ public void LessThanOrEqual_Should_Succeed(AngleDegrees left, AngleDegrees right [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void GreaterThan_Should_Succeed(AngleDegrees left, AngleDegrees right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -354,6 +277,7 @@ public void GreaterThan_Should_Succeed(AngleDegrees left, AngleDegrees right, bo [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void GreaterThanOrEqual_Should_Succeed(AngleDegrees left, AngleDegrees right, bool lessThan, bool equal, bool greaterThan) { // arrange diff --git a/NetFabric.Angle.UnitTests/AngleGradiansTests.cs b/NetFabric.Angle.UnitTests/AngleGradiansTests.cs index 537fa60..ec762a2 100644 --- a/NetFabric.Angle.UnitTests/AngleGradiansTests.cs +++ b/NetFabric.Angle.UnitTests/AngleGradiansTests.cs @@ -1,5 +1,6 @@ using FluentAssertions; using System; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Runtime.Serialization.Formatters.Binary; @@ -11,54 +12,6 @@ public class AngleGradiansTests { static readonly AngleGradians AcuteAngle = AngleGradians.Right / 2.0; - public static TheoryData AngleRadiansData = new TheoryData - { - { -AngleRadians.Full, -AngleGradians.Full }, - { -AngleRadians.Straight, -AngleGradians.Straight }, - { -AngleRadians.Right, -AngleGradians.Right }, - { AngleRadians.Zero, AngleGradians.Zero }, - { AngleRadians.Right, AngleGradians.Right }, - { AngleRadians.Straight, AngleGradians.Straight }, - { AngleRadians.Full, AngleGradians.Full }, - }; - - [Theory] - [MemberData(nameof(AngleRadiansData))] - public void ToGradians_When_AngleRadians_Should_Succeed(AngleRadians value, AngleGradians expected) - { - // arrange - - // act - var angle = Angle.ToGradians(value); - - // assert - angle.Should().BeOfType().And.Be(expected); - } - - public static TheoryData AngleDegreesData = new TheoryData - { - { -AngleDegrees.Full, -AngleGradians.Full }, - { -AngleDegrees.Straight, -AngleGradians.Straight }, - { -AngleDegrees.Right, -AngleGradians.Right }, - { AngleDegrees.Zero, AngleGradians.Zero }, - { AngleDegrees.Right, AngleGradians.Right }, - { AngleDegrees.Straight, AngleGradians.Straight }, - { AngleDegrees.Full, AngleGradians.Full }, - }; - - [Theory] - [MemberData(nameof(AngleDegreesData))] - public void ToGradians_When_AngleDegrees_Should_Succeed(AngleDegrees value, AngleGradians expected) - { - // arrange - - // act - var angle = Angle.ToGradians(value); - - // assert - angle.Should().BeOfType().And.Be(expected); - } - public static TheoryData SerializableData = new TheoryData { -AngleGradians.Full, @@ -126,6 +79,7 @@ public void Serializable_Should_Succeed(AngleGradians angle) [Theory] [MemberData(nameof(CompareInvalidData))] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void EqualsObject_Should_Succeed(AngleGradians left, object right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -139,6 +93,7 @@ public void EqualsObject_Should_Succeed(AngleGradians left, object right, bool l [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void Equals_Should_Succeed(AngleGradians left, AngleGradians right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -152,6 +107,7 @@ public void Equals_Should_Succeed(AngleGradians left, AngleGradians right, bool [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void GetHashCode_Should_Succeed(AngleGradians left, AngleGradians right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -168,6 +124,7 @@ public void GetHashCode_Should_Succeed(AngleGradians left, AngleGradians right, [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void OperatorEquality_Should_Succeed(AngleGradians left, AngleGradians right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -181,6 +138,7 @@ public void OperatorEquality_Should_Succeed(AngleGradians left, AngleGradians ri [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void OperatorInequality_Should_Succeed(AngleGradians left, AngleGradians right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -194,6 +152,7 @@ public void OperatorInequality_Should_Succeed(AngleGradians left, AngleGradians [Theory] [MemberData(nameof(CompareInvalidData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void CompareTo_When_InvalidData_Should_Thrown(AngleGradians angle, object obj, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -209,6 +168,7 @@ public void CompareTo_When_InvalidData_Should_Thrown(AngleGradians angle, object [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void CompareTo_Should_Succeed(AngleGradians left, AngleGradians right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -227,6 +187,7 @@ public void CompareTo_Should_Succeed(AngleGradians left, AngleGradians right, bo [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void Compare_Should_Succeed(AngleGradians left, AngleGradians right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -245,6 +206,7 @@ public void Compare_Should_Succeed(AngleGradians left, AngleGradians right, bool [Theory] [MemberData(nameof(CompareReducedData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void CompareReduced_Should_Succeed(AngleGradians left, AngleGradians right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -263,6 +225,7 @@ public void CompareReduced_Should_Succeed(AngleGradians left, AngleGradians righ [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void LessThan_Should_Succeed(AngleGradians left, AngleGradians right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -276,6 +239,7 @@ public void LessThan_Should_Succeed(AngleGradians left, AngleGradians right, boo [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void LessThanOrEqual_Should_Succeed(AngleGradians left, AngleGradians right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -289,6 +253,7 @@ public void LessThanOrEqual_Should_Succeed(AngleGradians left, AngleGradians rig [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void GreaterThan_Should_Succeed(AngleGradians left, AngleGradians right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -302,6 +267,7 @@ public void GreaterThan_Should_Succeed(AngleGradians left, AngleGradians right, [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void GreaterThanOrEqual_Should_Succeed(AngleGradians left, AngleGradians right, bool lessThan, bool equal, bool greaterThan) { // arrange diff --git a/NetFabric.Angle.UnitTests/AngleRadiansTests.cs b/NetFabric.Angle.UnitTests/AngleRadiansTests.cs index 0f53019..beb9b32 100644 --- a/NetFabric.Angle.UnitTests/AngleRadiansTests.cs +++ b/NetFabric.Angle.UnitTests/AngleRadiansTests.cs @@ -1,5 +1,6 @@ using FluentAssertions; using System; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Runtime.Serialization.Formatters.Binary; @@ -11,54 +12,6 @@ public class AngleRadiansTests { static readonly AngleRadians AcuteAngle = AngleRadians.Right / 2.0; - public static TheoryData AngleDegreesData = new TheoryData - { - { -AngleDegrees.Full, -AngleRadians.Full }, - { -AngleDegrees.Straight, -AngleRadians.Straight }, - { -AngleDegrees.Right, -AngleRadians.Right }, - { AngleDegrees.Zero, AngleRadians.Zero }, - { AngleDegrees.Right, AngleRadians.Right }, - { AngleDegrees.Straight, AngleRadians.Straight }, - { AngleDegrees.Full, AngleRadians.Full }, - }; - - [Theory] - [MemberData(nameof(AngleDegreesData))] - public void ToRadians_When_AngleDegrees_Should_Succeed(AngleDegrees value, AngleRadians expected) - { - // arrange - - // act - var angle = Angle.ToRadians(value); - - // assert - angle.Should().BeOfType().And.Be(expected); - } - - public static TheoryData AngleGradiansData = new TheoryData - { - { -AngleGradians.Full, -AngleRadians.Full }, - { -AngleGradians.Straight, -AngleRadians.Straight }, - { -AngleGradians.Right, -AngleRadians.Right }, - { AngleGradians.Zero, AngleRadians.Zero }, - { AngleGradians.Right, AngleRadians.Right }, - { AngleGradians.Straight, AngleRadians.Straight }, - { AngleGradians.Full, AngleRadians.Full }, - }; - - [Theory] - [MemberData(nameof(AngleGradiansData))] - public void ToRadians_When_AngleGradians_Should_Succeed(AngleGradians value, AngleRadians expected) - { - // arrange - - // act - var angle = Angle.ToRadians(value); - - // assert - angle.Should().BeOfType().And.Be(expected); - } - public static TheoryData SerializableData = new TheoryData { -AngleGradians.Full, @@ -126,6 +79,7 @@ public void Serializable_Should_Succeed(AngleGradians angle) [Theory] [MemberData(nameof(CompareInvalidData))] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void EqualsObject_Should_Succeed(AngleRadians left, object right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -139,6 +93,7 @@ public void EqualsObject_Should_Succeed(AngleRadians left, object right, bool le [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void Equals_Should_Succeed(AngleRadians left, AngleRadians right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -152,6 +107,8 @@ public void Equals_Should_Succeed(AngleRadians left, AngleRadians right, bool le [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void GetHashCode_Should_Succeed(AngleRadians left, AngleRadians right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -168,6 +125,7 @@ public void GetHashCode_Should_Succeed(AngleRadians left, AngleRadians right, bo [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void OperatorEquality_Should_Succeed(AngleRadians left, AngleRadians right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -181,6 +139,7 @@ public void OperatorEquality_Should_Succeed(AngleRadians left, AngleRadians righ [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void OperatorInequality_Should_Succeed(AngleRadians left, AngleRadians right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -194,6 +153,7 @@ public void OperatorInequality_Should_Succeed(AngleRadians left, AngleRadians ri [Theory] [MemberData(nameof(CompareInvalidData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void CompareTo_When_InvalidData_Should_Thrown(AngleRadians angle, object obj, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -209,6 +169,7 @@ public void CompareTo_When_InvalidData_Should_Thrown(AngleRadians angle, object [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void CompareTo_Should_Succeed(AngleRadians left, AngleRadians right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -227,6 +188,7 @@ public void CompareTo_Should_Succeed(AngleRadians left, AngleRadians right, bool [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void Compare_Should_Succeed(AngleRadians left, AngleRadians right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -245,6 +207,7 @@ public void Compare_Should_Succeed(AngleRadians left, AngleRadians right, bool l [Theory] [MemberData(nameof(CompareReducedData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void CompareReduced_Should_Succeed(AngleRadians left, AngleRadians right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -263,6 +226,7 @@ public void CompareReduced_Should_Succeed(AngleRadians left, AngleRadians right, [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void LessThan_Should_Succeed(AngleRadians left, AngleRadians right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -276,6 +240,7 @@ public void LessThan_Should_Succeed(AngleRadians left, AngleRadians right, bool [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void LessThanOrEqual_Should_Succeed(AngleRadians left, AngleRadians right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -289,6 +254,7 @@ public void LessThanOrEqual_Should_Succeed(AngleRadians left, AngleRadians right [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void GreaterThan_Should_Succeed(AngleRadians left, AngleRadians right, bool lessThan, bool equal, bool greaterThan) { // arrange @@ -302,6 +268,7 @@ public void GreaterThan_Should_Succeed(AngleRadians left, AngleRadians right, bo [Theory] [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] public void GreaterThanOrEqual_Should_Succeed(AngleRadians left, AngleRadians right, bool lessThan, bool equal, bool greaterThan) { // arrange diff --git a/NetFabric.Angle.UnitTests/AngleRevolutionsTests.cs b/NetFabric.Angle.UnitTests/AngleRevolutionsTests.cs new file mode 100644 index 0000000..325f418 --- /dev/null +++ b/NetFabric.Angle.UnitTests/AngleRevolutionsTests.cs @@ -0,0 +1,674 @@ +using FluentAssertions; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; +using Xunit; + +namespace NetFabric.UnitTests +{ + public class AngleRevolutionsTests + { + static readonly AngleRevolutions AcuteAngle = AngleRevolutions.Right / 2.0; + + public static TheoryData SerializableData = new TheoryData + { + -AngleRevolutions.Full, + -AngleRevolutions.Straight, + -AngleRevolutions.Right, + AngleRevolutions.Zero, + AngleRevolutions.Right, + AngleRevolutions.Straight, + AngleRevolutions.Full, + }; + + [Theory] + [MemberData(nameof(SerializableData))] + public void Serializable_Should_Succeed(AngleRevolutions angle) + { + // arrange + var formatter = new BinaryFormatter(); + var stream = new MemoryStream(); + + // act + formatter.Serialize(stream, angle); + stream.Seek(0, SeekOrigin.Begin); + var result = (AngleRevolutions)formatter.Deserialize(stream); + + // assert + result.Should().Be(angle); + } + + public static TheoryData CompareInvalidData => new TheoryData + { + { AngleRevolutions.Right, null, false, false, false }, + { AngleRevolutions.Right, 90.0, false, false, false }, + }; + + public static TheoryData CompareData => new TheoryData + { + { AngleRevolutions.Zero, AngleRevolutions.Right - AngleRevolutions.Full, false, false, true }, + { AngleRevolutions.Right, AngleRevolutions.Right - AngleRevolutions.Full, false, false, true }, + { AngleRevolutions.Straight, AngleRevolutions.Right - AngleRevolutions.Full, false, false, true }, + + { AngleRevolutions.Zero, AngleRevolutions.Right, true, false, false }, + { AngleRevolutions.Right, AngleRevolutions.Right, false, true, false }, + { AngleRevolutions.Straight, AngleRevolutions.Right, false, false, true }, + + { AngleRevolutions.Zero, AngleRevolutions.Right + AngleRevolutions.Full, true, false, false }, + { AngleRevolutions.Right, AngleRevolutions.Right + AngleRevolutions.Full, true, false, false }, + { AngleRevolutions.Straight, AngleRevolutions.Right + AngleRevolutions.Full, true, false, false }, + }; + + public static TheoryData CompareReducedData => new TheoryData + { + { AngleRevolutions.Zero, AngleRevolutions.Right - AngleRevolutions.Full, true, false, false }, + { AngleRevolutions.Right, AngleRevolutions.Right - AngleRevolutions.Full, false, true, false }, + { AngleRevolutions.Straight, AngleRevolutions.Right - AngleRevolutions.Full, false, false, true }, + + { AngleRevolutions.Zero, AngleRevolutions.Right, true, false, false }, + { AngleRevolutions.Right, AngleRevolutions.Right, false, true, false }, + { AngleRevolutions.Straight, AngleRevolutions.Right, false, false, true }, + + { AngleRevolutions.Zero, AngleRevolutions.Right + AngleRevolutions.Full, true, false, false }, + { AngleRevolutions.Right, AngleRevolutions.Right + AngleRevolutions.Full, false, true, false }, + { AngleRevolutions.Straight, AngleRevolutions.Right + AngleRevolutions.Full, false, false, true }, + }; + + [Theory] + [MemberData(nameof(CompareInvalidData))] + [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] + public void EqualsObject_Should_Succeed(AngleRevolutions left, object right, bool lessThan, bool equal, bool greaterThan) + { + // arrange + + // act + var result = left.Equals(right); + + // assert + result.Should().Be(equal); + } + + [Theory] + [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] + public void Equals_Should_Succeed(AngleRevolutions left, AngleRevolutions right, bool lessThan, bool equal, bool greaterThan) + { + // arrange + + // act + var result = left.Equals(right); + + // assert + result.Should().Be(equal); + } + + [Theory] + [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] + public void GetHashCode_Should_Succeed(AngleRevolutions left, AngleRevolutions right, bool lessThan, bool equal, bool greaterThan) + { + // arrange + + // act + var result = left.GetHashCode(); + + // assert + if (equal) + result.Should().Be(right.GetHashCode()); + else + result.Should().NotBe(right.GetHashCode()); + } + + [Theory] + [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] + public void OperatorEquality_Should_Succeed(AngleRevolutions left, AngleRevolutions right, bool lessThan, bool equal, bool greaterThan) + { + // arrange + + // act + var result = left == right; + + // assert + result.Should().Be(equal); + } + + [Theory] + [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] + public void OperatorInequality_Should_Succeed(AngleRevolutions left, AngleRevolutions right, bool lessThan, bool equal, bool greaterThan) + { + // arrange + + // act + var result = left != right; + + // assert + result.Should().Be(!equal); + } + + [Theory] + [MemberData(nameof(CompareInvalidData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] + public void CompareTo_When_InvalidData_Should_Thrown(AngleRevolutions angle, object obj, bool lessThan, bool equal, bool greaterThan) + { + // arrange + + // act + Action act = () => ((IComparable)angle).CompareTo(obj); + + // assert + act.Should() + .Throw() + .WithMessage($"Argument has to be an {nameof(AngleRevolutions)}.*"); + } + + [Theory] + [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] + public void CompareTo_Should_Succeed(AngleRevolutions left, AngleRevolutions right, bool lessThan, bool equal, bool greaterThan) + { + // arrange + + // act + var result = ((IComparable)left).CompareTo(right); + + // assert + if (lessThan) + result.Should().BeNegative(); + else if (equal) + result.Should().Be(0); + else + result.Should().BePositive(); + } + + [Theory] + [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] + public void Compare_Should_Succeed(AngleRevolutions left, AngleRevolutions right, bool lessThan, bool equal, bool greaterThan) + { + // arrange + + // act + var result = Angle.Compare(left, right); + + // assert + if (lessThan) + result.Should().BeNegative(); + else if (equal) + result.Should().Be(0); + else + result.Should().BePositive(); + } + + [Theory] + [MemberData(nameof(CompareReducedData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] + public void CompareReduced_Should_Succeed(AngleRevolutions left, AngleRevolutions right, bool lessThan, bool equal, bool greaterThan) + { + // arrange + + // act + var result = Angle.CompareReduced(left, right); + + // assert + if (lessThan) + result.Should().BeNegative(); + else if (equal) + result.Should().Be(0); + else + result.Should().BePositive(); + } + + [Theory] + [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] + public void LessThan_Should_Succeed(AngleRevolutions left, AngleRevolutions right, bool lessThan, bool equal, bool greaterThan) + { + // arrange + + // act + var result = left < right; + + // assert + result.Should().Be(lessThan); + } + + [Theory] + [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] + public void LessThanOrEqual_Should_Succeed(AngleRevolutions left, AngleRevolutions right, bool lessThan, bool equal, bool greaterThan) + { + // arrange + + // act + var result = left <= right; + + // assert + result.Should().Be(lessThan || equal); + } + + [Theory] + [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] + public void GreaterThan_Should_Succeed(AngleRevolutions left, AngleRevolutions right, bool lessThan, bool equal, bool greaterThan) + { + // arrange + + // act + var result = left > right; + + // assert + result.Should().Be(greaterThan); + } + + [Theory] + [MemberData(nameof(CompareData))] + [SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")] + public void GreaterThanOrEqual_Should_Succeed(AngleRevolutions left, AngleRevolutions right, bool lessThan, bool equal, bool greaterThan) + { + // arrange + + // act + var result = left >= right; + + // assert + result.Should().Be(greaterThan || equal); + } + + public static TheoryData ReduceData => new TheoryData { + { AngleRevolutions.Zero, AngleRevolutions.Zero }, + { AcuteAngle, AcuteAngle }, + { AngleRevolutions.Right, AngleRevolutions.Right }, + { AngleRevolutions.Right + AcuteAngle, AngleRevolutions.Right + AcuteAngle }, + { AngleRevolutions.Straight, AngleRevolutions.Straight }, + + { AngleRevolutions.Full, AngleRevolutions.Zero }, + { AngleRevolutions.Full + AcuteAngle, AcuteAngle }, + { AngleRevolutions.Full + AngleRevolutions.Right, AngleRevolutions.Right }, + { AngleRevolutions.Full + AngleRevolutions.Right + AcuteAngle, AngleRevolutions.Right + AcuteAngle }, + { AngleRevolutions.Full + AngleRevolutions.Straight, AngleRevolutions.Straight }, + + { -AngleRevolutions.Full, AngleRevolutions.Zero }, + { -AcuteAngle, AngleRevolutions.Full - AcuteAngle }, + { -AngleRevolutions.Right, AngleRevolutions.Full - AngleRevolutions.Right }, + { -AngleRevolutions.Straight, AngleRevolutions.Straight }, + { -AngleRevolutions.Straight - AngleRevolutions.Right, AngleRevolutions.Right }, + }; + + [Theory] + [MemberData(nameof(ReduceData))] + public void Reduce_Should_Succeed(AngleRevolutions angle, AngleRevolutions expected) + { + // arrange + + // act + var result = Angle.Reduce(angle); + + // assert + result.Revolutions.Should().BeApproximately(expected.Revolutions, Math.Pow(10, 8)); + } + + public static TheoryData QuadrantData => new TheoryData { + {AngleRevolutions.Zero, Quadrant.First}, + {AcuteAngle, Quadrant.First}, + {AngleRevolutions.Right, Quadrant.Second}, + {AngleRevolutions.Right + AcuteAngle, Quadrant.Second}, + {AngleRevolutions.Straight, Quadrant.Third}, + {AngleRevolutions.Straight + AcuteAngle, Quadrant.Third}, + {AngleRevolutions.Straight + AngleRevolutions.Right, Quadrant.Fourth}, + {AngleRevolutions.Straight + AngleRevolutions.Right + AcuteAngle, Quadrant.Fourth}, + + {AngleRevolutions.Full, Quadrant.First}, + {AngleRevolutions.Full + AcuteAngle, Quadrant.First}, + {AngleRevolutions.Full + AngleRevolutions.Right, Quadrant.Second}, + {AngleRevolutions.Full + AngleRevolutions.Right + AcuteAngle, Quadrant.Second}, + {AngleRevolutions.Full + AngleRevolutions.Straight, Quadrant.Third}, + {AngleRevolutions.Full + AngleRevolutions.Straight + AcuteAngle, Quadrant.Third}, + {AngleRevolutions.Full + AngleRevolutions.Straight + AngleRevolutions.Right, Quadrant.Fourth}, + {AngleRevolutions.Full + AngleRevolutions.Straight + AngleRevolutions.Right + AcuteAngle, Quadrant.Fourth}, + }; + + [Theory] + [MemberData(nameof(QuadrantData))] + public void GetQuadrant_Should_Succeed(AngleRevolutions angle, Quadrant expected) + { + // arrange + + // act + var result = Angle.GetQuadrant(angle); + + // assert + result.Should().Be(expected); + } + + public static TheoryData ReferencetData => new TheoryData { + {AngleRevolutions.Zero, AngleRevolutions.Zero}, + {AcuteAngle, AcuteAngle}, + {AngleRevolutions.Right ,AngleRevolutions.Right}, + {AngleRevolutions.Right + AcuteAngle, AcuteAngle}, + {AngleRevolutions.Straight, AngleRevolutions.Zero}, + {AngleRevolutions.Straight + AcuteAngle, AcuteAngle}, + {AngleRevolutions.Straight + AngleRevolutions.Right, AngleRevolutions.Right}, + {AngleRevolutions.Straight + AngleRevolutions.Right + AcuteAngle, AcuteAngle}, + {AngleRevolutions.Full, AngleRevolutions.Zero}, + }; + + [Theory] + [MemberData(nameof(ReferencetData))] + public void Reference_Should_Succeed(AngleRevolutions angle, AngleRevolutions expected) + { + // arrange + + // act + var result = Angle.GetReference(angle); + + // assert + result.Should().Be(expected); + } + + public static TheoryData IsZeroData => new TheoryData { + {AngleRevolutions.Zero, true}, + {AcuteAngle, false}, + {AngleRevolutions.Right, false}, + {AngleRevolutions.Right + AcuteAngle, false}, + {AngleRevolutions.Straight, false}, + {AngleRevolutions.Straight + AngleRevolutions.Right, false}, + {AngleRevolutions.Full, true}, + + {-AcuteAngle, false}, + {-AngleRevolutions.Right, false}, + {-AngleRevolutions.Right - AcuteAngle, false}, + {-AngleRevolutions.Straight, false}, + {-AngleRevolutions.Straight - AngleRevolutions.Right, false}, + {-AngleRevolutions.Full, true}, + }; + + [Theory] + [MemberData(nameof(IsZeroData))] + public void IsZero_Should_Succeed(AngleRevolutions angle, bool expected) + { + // arrange + + // act + var result = Angle.IsZero(angle); + + // assert + result.Should().Be(expected); + } + + public static TheoryData IsAcuteData => new TheoryData { + {AngleRevolutions.Zero, false}, + {AcuteAngle, true}, + {AngleRevolutions.Right, false}, + {AngleRevolutions.Right + AcuteAngle, false}, + {AngleRevolutions.Straight, false}, + {AngleRevolutions.Straight + AngleRevolutions.Right, false}, + {AngleRevolutions.Full, false}, + + {-AcuteAngle, true}, + {-AngleRevolutions.Right, false}, + {-AngleRevolutions.Right - AcuteAngle, false}, + {-AngleRevolutions.Straight, false}, + {-AngleRevolutions.Straight - AngleRevolutions.Right, false}, + {-AngleRevolutions.Full, false}, + }; + + [Theory] + [MemberData(nameof(IsAcuteData))] + public void IsAcute_Should_Succeed(AngleRevolutions angle, bool expected) + { + // arrange + + // act + var result = Angle.IsAcute(angle); + + // assert + result.Should().Be(expected); + } + + public static TheoryData IsRightData => new TheoryData { + {AngleRevolutions.Zero, false}, + {AcuteAngle, false}, + {AngleRevolutions.Right, true}, + {AngleRevolutions.Right + AcuteAngle, false}, + {AngleRevolutions.Straight, false}, + {AngleRevolutions.Straight + AngleRevolutions.Right, false}, + {AngleRevolutions.Full, false}, + + {-AcuteAngle, false}, + {-AngleRevolutions.Right, true}, + {-AngleRevolutions.Right - AcuteAngle, false}, + {-AngleRevolutions.Straight, false}, + {-AngleRevolutions.Straight - AngleRevolutions.Right, false}, + {-AngleRevolutions.Full, false}, + }; + + [Theory] + [MemberData(nameof(IsRightData))] + public void IsRight_Should_Succeed(AngleRevolutions angle, bool expected) + { + // arrange + + // act + var result = Angle.IsRight(angle); + + // assert + result.Should().Be(expected); + } + + public static TheoryData IsObtuseData => new TheoryData { + {AngleRevolutions.Zero, false}, + {AcuteAngle, false}, + {AngleRevolutions.Right, false}, + {AngleRevolutions.Right + AcuteAngle, true}, + {AngleRevolutions.Straight, false}, + {AngleRevolutions.Straight + AngleRevolutions.Right, false}, + {AngleRevolutions.Full, false}, + + {-AcuteAngle, false}, + {-AngleRevolutions.Right, false}, + {-AngleRevolutions.Right - AcuteAngle, true}, + {-AngleRevolutions.Straight, false}, + {-AngleRevolutions.Straight - AngleRevolutions.Right, false}, + {-AngleRevolutions.Full, false}, + }; + + [Theory] + [MemberData(nameof(IsObtuseData))] + public void IsObtuse_Should_Succeed(AngleRevolutions angle, bool expected) + { + // arrange + + // act + var result = Angle.IsObtuse(angle); + + // assert + result.Should().Be(expected); + } + + public static TheoryData IsStraightData => new TheoryData { + {AngleRevolutions.Zero, false}, + {AcuteAngle, false}, + {AngleRevolutions.Right, false}, + {AngleRevolutions.Right - AcuteAngle, false}, + {AngleRevolutions.Straight, true}, + {AngleRevolutions.Straight - AngleRevolutions.Right, false}, + {AngleRevolutions.Full, false}, + + {-AcuteAngle, false}, + {-AngleRevolutions.Right, false}, + {-AngleRevolutions.Right - AcuteAngle, false}, + {-AngleRevolutions.Straight, true}, + {-AngleRevolutions.Straight - AngleRevolutions.Right, false}, + {-AngleRevolutions.Full, false}, + }; + + [Theory] + [MemberData(nameof(IsStraightData))] + public void IsStraight_Should_Succeed(AngleRevolutions angle, bool expected) + { + // arrange + + // act + var result = Angle.IsStraight(angle); + + // assert + result.Should().Be(expected); + } + + public static TheoryData IsReflexData => new TheoryData { + {AngleRevolutions.Zero, false}, + {AcuteAngle, false}, + {AngleRevolutions.Right, false}, + {AngleRevolutions.Right + AcuteAngle, false}, + {AngleRevolutions.Straight, false}, + {AngleRevolutions.Straight + AngleRevolutions.Right, true}, + {AngleRevolutions.Full, false}, + + {-AcuteAngle, false}, + {-AngleRevolutions.Right, false}, + {-AngleRevolutions.Right - AcuteAngle, false}, + {-AngleRevolutions.Straight, false}, + {-AngleRevolutions.Straight - AngleRevolutions.Right, true}, + {-AngleRevolutions.Full, false}, + }; + + [Theory] + [MemberData(nameof(IsReflexData))] + public void IsReflex_Should_Succeed(AngleRevolutions angle, bool expected) + { + // arrange + + // act + var result = Angle.IsReflex(angle); + + // assert + result.Should().Be(expected); + } + + public static TheoryData IsObliqueData => new TheoryData { + {AngleRevolutions.Zero, false}, + {AcuteAngle, true}, + {AngleRevolutions.Right, false}, + {AngleRevolutions.Right + AcuteAngle, true}, + {AngleRevolutions.Straight, false}, + {AngleRevolutions.Straight + AngleRevolutions.Right, false}, + {AngleRevolutions.Full, false}, + + {-AcuteAngle, true}, + {-AngleRevolutions.Right, false}, + {-AngleRevolutions.Right - AcuteAngle, true}, + {-AngleRevolutions.Straight, false}, + {-AngleRevolutions.Straight - AngleRevolutions.Right, false}, + {-AngleRevolutions.Full, false}, + }; + + [Theory] + [MemberData(nameof(IsObliqueData))] + public void IsOblique_Should_Succeed(AngleRevolutions angle, bool expected) + { + // arrange + + // act + var result = Angle.IsOblique(angle); + + // assert + result.Should().Be(expected); + } + + public static TheoryData LerpData => new TheoryData + { + {AcuteAngle, AngleRevolutions.Right + AcuteAngle, -0.5, AngleRevolutions.Zero}, + {AcuteAngle, AngleRevolutions.Right + AcuteAngle, 0.0, AcuteAngle}, + {AcuteAngle, AngleRevolutions.Right + AcuteAngle, 0.5, AngleRevolutions.Right}, + {AcuteAngle, AngleRevolutions.Right + AcuteAngle, 1.0, AngleRevolutions.Right + AcuteAngle}, + {AcuteAngle, AngleRevolutions.Right + AcuteAngle, 1.5, AngleRevolutions.Straight}, + + {-AcuteAngle, -AngleRevolutions.Right - AcuteAngle, -0.5, AngleRevolutions.Zero}, + {-AcuteAngle, -AngleRevolutions.Right - AcuteAngle, 0.0, -AcuteAngle}, + {-AcuteAngle, -AngleRevolutions.Right - AcuteAngle, 0.5, -AngleRevolutions.Right}, + {-AcuteAngle, -AngleRevolutions.Right - AcuteAngle, 1.0, -AngleRevolutions.Right - AcuteAngle}, + {-AcuteAngle, -AngleRevolutions.Right - AcuteAngle, 1.5, -AngleRevolutions.Straight}, + + {AngleRevolutions.Right + AcuteAngle, AcuteAngle, -0.5, AngleRevolutions.Straight}, + {AngleRevolutions.Right + AcuteAngle, AcuteAngle, 0.0, AngleRevolutions.Right + AcuteAngle}, + {AngleRevolutions.Right + AcuteAngle, AcuteAngle, 0.5, AngleRevolutions.Right}, + {AngleRevolutions.Right + AcuteAngle, AcuteAngle, 1.0, AcuteAngle}, + {AngleRevolutions.Right + AcuteAngle, AcuteAngle, 1.5, AngleRevolutions.Zero}, + }; + + [Theory] + [MemberData(nameof(LerpData))] + public void Lerp_Should_Succeed(AngleRevolutions a1, AngleRevolutions a2, double t, AngleRevolutions expected) + { + // arrange + + // act + var result = Angle.Lerp(a1, a2, t); + + // assert + result.Should().Be(expected); + } + + public static TheoryData ToStringData => new TheoryData + { + {AngleRevolutions.Straight, "0.5"}, + }; + + [Theory] + [MemberData(nameof(ToStringData))] + public void ToString_Should_Succeed(AngleRevolutions angle, string expected) + { + // arrange + CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture; + + // act + var result = angle.ToString(); + + // assert + result.Should().Be(expected); + } + + public static TheoryData ToStringFormatData => new TheoryData + { + {AngleRevolutions.Straight, "0.00", "0.50"}, + }; + + [Theory] + [MemberData(nameof(ToStringFormatData))] + public void ToStringFormat_Should_Succeed(AngleRevolutions angle, string format, string expected) + { + // arrange + CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture; + + // act + var result = angle.ToString(format); + + // assert + result.Should().Be(expected); + } + + public static TheoryData ToStringFormatCultureData => new TheoryData + { + {AngleRevolutions.Straight, "0.00", new CultureInfo("pt-PT"), "0,50"}, + }; + + [Theory] + [MemberData(nameof(ToStringFormatCultureData))] + public void ToStringFormatCulture_Should_Succeed(AngleRevolutions angle, string format, CultureInfo culture, string expected) + { + // arrange + + // act + var result = angle.ToString(format, culture); + + // assert + result.Should().Be(expected); + } + + } +} diff --git a/NetFabric.Angle.UnitTests/AngleTest.ToDegrees.cs b/NetFabric.Angle.UnitTests/AngleTest.ToDegrees.cs new file mode 100644 index 0000000..f5fde0a --- /dev/null +++ b/NetFabric.Angle.UnitTests/AngleTest.ToDegrees.cs @@ -0,0 +1,82 @@ +using FluentAssertions; +using System; +using Xunit; + +namespace NetFabric.UnitTests +{ + public partial class AngleTests + { + public static TheoryData GradiansToDegreesData = new TheoryData + { + { -AngleGradians.Full, -AngleDegrees.Full }, + { -AngleGradians.Straight, -AngleDegrees.Straight }, + { -AngleGradians.Right, -AngleDegrees.Right }, + { AngleGradians.Zero, AngleDegrees.Zero }, + { AngleGradians.Right, AngleDegrees.Right }, + { AngleGradians.Straight, AngleDegrees.Straight }, + { AngleGradians.Full, AngleDegrees.Full }, + }; + + [Theory] + [MemberData(nameof(GradiansToDegreesData))] + public void ToDegrees_With_AngleGradians_Should_Succeed(AngleGradians angle, AngleDegrees expected) + { + // arrange + + // act + var result = Angle.ToDegrees(angle); + + // assert + result.Should().Be(expected); + } + + public static TheoryData RadiansToDegreesData = new TheoryData + { + { -AngleRadians.Full, -AngleDegrees.Full }, + { -AngleRadians.Straight, -AngleDegrees.Straight }, + { -AngleRadians.Right, -AngleDegrees.Right }, + { AngleRadians.Zero, AngleDegrees.Zero }, + { AngleRadians.Right, AngleDegrees.Right }, + { AngleRadians.Straight, AngleDegrees.Straight }, + { AngleRadians.Full, AngleDegrees.Full }, + }; + + [Theory] + [MemberData(nameof(RadiansToDegreesData))] + public void ToDegrees_With_AngleRadians_Should_Succeed(AngleRadians angle, AngleDegrees expected) + { + // arrange + + // act + var result = Angle.ToDegrees(angle); + + // assert + result.Should().Be(expected); + } + + public static TheoryData RevolutionsToDegreesData = new TheoryData + { + { -AngleRevolutions.Full, -AngleDegrees.Full }, + { -AngleRevolutions.Straight, -AngleDegrees.Straight }, + { -AngleRevolutions.Right, -AngleDegrees.Right }, + { AngleRevolutions.Zero, AngleDegrees.Zero }, + { AngleRevolutions.Right, AngleDegrees.Right }, + { AngleRevolutions.Straight, AngleDegrees.Straight }, + { AngleRevolutions.Full, AngleDegrees.Full }, + }; + + [Theory] + [MemberData(nameof(RevolutionsToDegreesData))] + public void ToDegrees_With_AngleRevolutions_Should_Succeed(AngleRevolutions angle, AngleDegrees expected) + { + // arrange + + // act + var result = Angle.ToDegrees(angle); + + // assert + result.Should().Be(expected); + } + + } +} diff --git a/NetFabric.Angle.UnitTests/AngleTest.ToGradians.cs b/NetFabric.Angle.UnitTests/AngleTest.ToGradians.cs new file mode 100644 index 0000000..fdfeb76 --- /dev/null +++ b/NetFabric.Angle.UnitTests/AngleTest.ToGradians.cs @@ -0,0 +1,82 @@ +using FluentAssertions; +using System; +using Xunit; + +namespace NetFabric.UnitTests +{ + public partial class AngleTests + { + public static TheoryData DegreesToGradiansData = new TheoryData + { + { -AngleDegrees.Full, -AngleGradians.Full }, + { -AngleDegrees.Straight, -AngleGradians.Straight }, + { -AngleDegrees.Right, -AngleGradians.Right }, + { AngleDegrees.Zero, AngleGradians.Zero }, + { AngleDegrees.Right, AngleGradians.Right }, + { AngleDegrees.Straight, AngleGradians.Straight }, + { AngleDegrees.Full, AngleGradians.Full }, + }; + + [Theory] + [MemberData(nameof(DegreesToGradiansData))] + public void ToGradians_With_AngleDegrees_Should_Succeed(AngleDegrees angle, AngleGradians expected) + { + // arrange + + // act + var result = Angle.ToGradians(angle); + + // assert + result.Should().Be(expected); + } + + public static TheoryData RadiansToGradiansData = new TheoryData + { + { -AngleRadians.Full, -AngleGradians.Full }, + { -AngleRadians.Straight, -AngleGradians.Straight }, + { -AngleRadians.Right, -AngleGradians.Right }, + { AngleRadians.Zero, AngleGradians.Zero }, + { AngleRadians.Right, AngleGradians.Right }, + { AngleRadians.Straight, AngleGradians.Straight }, + { AngleRadians.Full, AngleGradians.Full }, + }; + + [Theory] + [MemberData(nameof(RadiansToGradiansData))] + public void ToGradians_With_AngleRadians_Should_Succeed(AngleRadians angle, AngleGradians expected) + { + // arrange + + // act + var result = Angle.ToGradians(angle); + + // assert + result.Should().Be(expected); + } + + public static TheoryData RevolutionsToGradiansData = new TheoryData + { + { -AngleRevolutions.Full, -AngleGradians.Full }, + { -AngleRevolutions.Straight, -AngleGradians.Straight }, + { -AngleRevolutions.Right, -AngleGradians.Right }, + { AngleRevolutions.Zero, AngleGradians.Zero }, + { AngleRevolutions.Right, AngleGradians.Right }, + { AngleRevolutions.Straight, AngleGradians.Straight }, + { AngleRevolutions.Full, AngleGradians.Full }, + }; + + [Theory] + [MemberData(nameof(RevolutionsToGradiansData))] + public void ToGradians_With_AngleRevolutions_Should_Succeed(AngleRevolutions angle, AngleGradians expected) + { + // arrange + + // act + var result = Angle.ToGradians(angle); + + // assert + result.Should().Be(expected); + } + + } +} diff --git a/NetFabric.Angle.UnitTests/AngleTest.ToRadians.cs b/NetFabric.Angle.UnitTests/AngleTest.ToRadians.cs new file mode 100644 index 0000000..f5cffc5 --- /dev/null +++ b/NetFabric.Angle.UnitTests/AngleTest.ToRadians.cs @@ -0,0 +1,82 @@ +using FluentAssertions; +using System; +using Xunit; + +namespace NetFabric.UnitTests +{ + public partial class AngleTests + { + public static TheoryData DegreesToRadiansData = new TheoryData + { + { -AngleDegrees.Full, -AngleRadians.Full }, + { -AngleDegrees.Straight, -AngleRadians.Straight }, + { -AngleDegrees.Right, -AngleRadians.Right }, + { AngleDegrees.Zero, AngleRadians.Zero }, + { AngleDegrees.Right, AngleRadians.Right }, + { AngleDegrees.Straight, AngleRadians.Straight }, + { AngleDegrees.Full, AngleRadians.Full }, + }; + + [Theory] + [MemberData(nameof(DegreesToRadiansData))] + public void ToRadians_With_AngleRadians_Should_Succeed(AngleDegrees angle, AngleRadians expected) + { + // arrange + + // act + var result = Angle.ToRadians(angle); + + // assert + result.Should().Be(expected); + } + + public static TheoryData GradiansToRadiansData = new TheoryData + { + { -AngleGradians.Full, -AngleRadians.Full }, + { -AngleGradians.Straight, -AngleRadians.Straight }, + { -AngleGradians.Right, -AngleRadians.Right }, + { AngleGradians.Zero, AngleRadians.Zero }, + { AngleGradians.Right, AngleRadians.Right }, + { AngleGradians.Straight, AngleRadians.Straight }, + { AngleGradians.Full, AngleRadians.Full }, + }; + + [Theory] + [MemberData(nameof(GradiansToRadiansData))] + public void ToRadians_With_AngleGradians_Should_Succeed(AngleGradians angle, AngleRadians expected) + { + // arrange + + // act + var result = Angle.ToRadians(angle); + + // assert + result.Should().Be(expected); + } + + public static TheoryData RevolutionsToRadiansData = new TheoryData + { + { -AngleRevolutions.Full, -AngleRadians.Full }, + { -AngleRevolutions.Straight, -AngleRadians.Straight }, + { -AngleRevolutions.Right, -AngleRadians.Right }, + { AngleRevolutions.Zero, AngleRadians.Zero }, + { AngleRevolutions.Right, AngleRadians.Right }, + { AngleRevolutions.Straight, AngleRadians.Straight }, + { AngleRevolutions.Full, AngleRadians.Full }, + }; + + [Theory] + [MemberData(nameof(RevolutionsToRadiansData))] + public void ToRadians_With_AngleRevolutions_Should_Succeed(AngleRevolutions angle, AngleRadians expected) + { + // arrange + + // act + var result = Angle.ToRadians(angle); + + // assert + result.Should().Be(expected); + } + + } +} diff --git a/NetFabric.Angle.UnitTests/AngleTest.ToRevolutions.cs b/NetFabric.Angle.UnitTests/AngleTest.ToRevolutions.cs new file mode 100644 index 0000000..7a36268 --- /dev/null +++ b/NetFabric.Angle.UnitTests/AngleTest.ToRevolutions.cs @@ -0,0 +1,82 @@ +using FluentAssertions; +using System; +using Xunit; + +namespace NetFabric.UnitTests +{ + public partial class AngleTests + { + public static TheoryData DegreesToRevolutionsData = new TheoryData + { + { -AngleDegrees.Full, -AngleRevolutions.Full }, + { -AngleDegrees.Straight, -AngleRevolutions.Straight }, + { -AngleDegrees.Right, -AngleRevolutions.Right }, + { AngleDegrees.Zero, AngleRevolutions.Zero }, + { AngleDegrees.Right, AngleRevolutions.Right }, + { AngleDegrees.Straight, AngleRevolutions.Straight }, + { AngleDegrees.Full, AngleRevolutions.Full }, + }; + + [Theory] + [MemberData(nameof(DegreesToRevolutionsData))] + public void ToRevolutions_With_AngleDegrees_Should_Succeed(AngleDegrees angle, AngleRevolutions expected) + { + // arrange + + // act + var result = Angle.ToRevolutions(angle); + + // assert + result.Should().Be(expected); + } + + public static TheoryData GradiansToRevolutionsData = new TheoryData + { + { -AngleGradians.Full, -AngleRevolutions.Full }, + { -AngleGradians.Straight, -AngleRevolutions.Straight }, + { -AngleGradians.Right, -AngleRevolutions.Right }, + { AngleGradians.Zero, AngleRevolutions.Zero }, + { AngleGradians.Right, AngleRevolutions.Right }, + { AngleGradians.Straight, AngleRevolutions.Straight }, + { AngleGradians.Full, AngleRevolutions.Full }, + }; + + [Theory] + [MemberData(nameof(GradiansToRevolutionsData))] + public void ToRevolutions_With_AngleGradians_Should_Succeed(AngleGradians angle, AngleRevolutions expected) + { + // arrange + + // act + var result = Angle.ToRevolutions(angle); + + // assert + result.Should().Be(expected); + } + + public static TheoryData RadiansToRevolutionsData = new TheoryData + { + { -AngleRadians.Full, -AngleRevolutions.Full }, + { -AngleRadians.Straight, -AngleRevolutions.Straight }, + { -AngleRadians.Right, -AngleRevolutions.Right }, + { AngleRadians.Zero, AngleRevolutions.Zero }, + { AngleRadians.Right, AngleRevolutions.Right }, + { AngleRadians.Straight, AngleRevolutions.Straight }, + { AngleRadians.Full, AngleRevolutions.Full }, + }; + + [Theory] + [MemberData(nameof(RadiansToRevolutionsData))] + public void ToRevolutions_With_AngleRadians_Should_Succeed(AngleRadians angle, AngleRevolutions expected) + { + // arrange + + // act + var result = Angle.ToRevolutions(angle); + + // assert + result.Should().Be(expected); + } + + } +} diff --git a/NetFabric.Angle.UnitTests/AngleTest.cs b/NetFabric.Angle.UnitTests/AngleTest.cs index 33e28fd..8bd77a2 100644 --- a/NetFabric.Angle.UnitTests/AngleTest.cs +++ b/NetFabric.Angle.UnitTests/AngleTest.cs @@ -4,7 +4,7 @@ namespace NetFabric.UnitTests { - public class AngleTests + public partial class AngleTests { public static TheoryData DoubleData = new TheoryData { @@ -17,6 +17,22 @@ public class AngleTests double.NegativeInfinity, }; + public static TheoryData DegreesMinutesData = new TheoryData + { + { 40, 0.0, Angle.FromDegrees(40) }, + { -40, 0.0, Angle.FromDegrees(-40) }, + { 40, 30.0, Angle.FromDegrees(40.5) }, + { -40, 30.0, Angle.FromDegrees(-40.5) }, + }; + + public static TheoryData DegreesMinutesSecondsData = new TheoryData + { + { 40, 0, 0.0, Angle.FromDegrees(40) }, + { -40, 0, 0.0, Angle.FromDegrees(-40) }, + { 40, 30, 30.0, Angle.FromDegrees(40.50833) }, + { -40, 30, 30.0, Angle.FromDegrees(-40.50833) }, + }; + [Theory] [MemberData(nameof(DoubleData))] public void FromRadians_Should_Succeed(double value) @@ -45,6 +61,32 @@ public void FromDegrees_Should_Succeed(double value) angle.Degrees.Should().Be(value); } + [Theory] + [MemberData(nameof(DegreesMinutesData))] + public void FromDegrees_When_AngleMinutes_Should_Succeed(int degrees, double minutes, AngleDegrees expected) + { + // arrange + + // act + var angle = Angle.FromDegrees(degrees, minutes); + + // assert + angle.Degrees.Should().BeApproximately(expected.Degrees, 0.0001); + } + + [Theory] + [MemberData(nameof(DegreesMinutesSecondsData))] + public void FromDegrees_When_AngleMinutesSeconds_Should_Succeed(int degrees, int minutes, double seconds, AngleDegrees expected) + { + // arrange + + // act + var angle = Angle.FromDegrees(degrees, minutes, seconds); + + // assert + angle.Degrees.Should().BeApproximately(expected.Degrees, 0.0001); + } + [Theory] [MemberData(nameof(DoubleData))] public void FromGradians_Should_Succeed(double value) @@ -59,5 +101,18 @@ public void FromGradians_Should_Succeed(double value) angle.Gradians.Should().Be(value); } + [Theory] + [MemberData(nameof(DoubleData))] + public void FromRevolutions_Should_Succeed(double value) + { + // arrange + + // act + var angle = Angle.FromRevolutions(value); + + // assert + angle.Should().BeOfType(); + angle.Revolutions.Should().Be(value); + } } } diff --git a/NetFabric.Angle/Angle.cs b/NetFabric.Angle/Angle.cs index 9b1dff4..e146890 100644 --- a/NetFabric.Angle/Angle.cs +++ b/NetFabric.Angle/Angle.cs @@ -13,7 +13,7 @@ public static partial class Angle const double GradiansInDegrees = AngleGradians.FullAngle / AngleDegrees.FullAngle; /// - /// Returns an RadiansAngle that represents the equivalent to the DegreesAngle. + /// Returns an that represents the equivalent to the . /// /// An angle in degrees. /// An object that represents value. @@ -22,16 +22,25 @@ public static AngleRadians ToRadians(AngleDegrees angle) => new AngleRadians(angle.Degrees / DegreesInRadians); /// - /// Returns an RadiansAngle that represents the equivalent to the GradiansAngle. + /// Returns an that represents the equivalent to the . /// - /// An angle in degrees. + /// An angle in gradians. /// An object that represents value. [Pure] public static AngleRadians ToRadians(AngleGradians angle) => new AngleRadians(angle.Gradians / GradiansInRadians); /// - /// Returns an DegreessAngle that represents the equivalent to the RadiansAngle. + /// Returns an that represents the equivalent to the . + /// + /// An angle in revolutions. + /// An object that represents value. + [Pure] + public static AngleRadians ToRadians(AngleRevolutions angle) => + new AngleRadians(angle.Revolutions * AngleRadians.FullAngle); + + /// + /// Returns an that represents the equivalent to the . /// /// An angle in radians. /// An object that represents value. @@ -40,16 +49,25 @@ public static AngleDegrees ToDegrees(AngleRadians angle) => new AngleDegrees(angle.Radians * DegreesInRadians); /// - /// Returns an DegreessAngle that represents the equivalent to the GradiansAngle. + /// Returns an that represents the equivalent to the . /// - /// An angle in radians. + /// An angle in gradians. /// An object that represents value. [Pure] public static AngleDegrees ToDegrees(AngleGradians angle) => new AngleDegrees(angle.Gradians / GradiansInDegrees); /// - /// Returns an GradianssAngle that represents the equivalent to the RadiansAngle. + /// Returns an that represents the equivalent to the . + /// + /// An angle in revolutions. + /// An object that represents value. + [Pure] + public static AngleDegrees ToDegrees(AngleRevolutions angle) => + new AngleDegrees(angle.Revolutions * AngleDegrees.FullAngle); + + /// + /// Returns an that represents the equivalent to the . /// /// An angle in radians. /// An object that represents value. @@ -58,12 +76,48 @@ public static AngleGradians ToGradians(AngleRadians angle) => new AngleGradians(angle.Radians * GradiansInRadians); /// - /// Returns an GradianssAngle that represents the equivalent to the DegreesAngle. + /// Returns an that represents the equivalent to the . /// - /// An angle in radians. + /// An angle in degrees. /// An object that represents value. [Pure] public static AngleGradians ToGradians(AngleDegrees angle) => new AngleGradians(angle.Degrees * GradiansInDegrees); + + /// + /// Returns an that represents the equivalent to the . + /// + /// An angle in revolutions. + /// An object that represents value. + [Pure] + public static AngleGradians ToGradians(AngleRevolutions angle) => + new AngleGradians(angle.Revolutions * AngleGradians.FullAngle); + + /// + /// Returns an that represents the equivalent to the . + /// + /// An angle in degrees. + /// An object that represents value. + [Pure] + public static AngleRevolutions ToRevolutions(AngleDegrees angle) => + new AngleRevolutions(angle.Degrees / AngleDegrees.FullAngle); + + /// + /// Returns an that represents the equivalent to the . + /// + /// An angle in degrees. + /// An object that represents value. + [Pure] + public static AngleRevolutions ToRevolutions(AngleGradians angle) => + new AngleRevolutions(angle.Gradians / AngleGradians.FullAngle); + + /// + /// Returns an that represents the equivalent to the . + /// + /// An angle in degrees. + /// An object that represents value. + [Pure] + public static AngleRevolutions ToRevolutions(AngleRadians angle) => + new AngleRevolutions(angle.Radians / AngleRadians.FullAngle); } } diff --git a/NetFabric.Angle/AngleRevolutions.cs b/NetFabric.Angle/AngleRevolutions.cs new file mode 100644 index 0000000..64331e8 --- /dev/null +++ b/NetFabric.Angle/AngleRevolutions.cs @@ -0,0 +1,562 @@ +using System; +using System.Diagnostics; +using System.Diagnostics.Contracts; + +namespace NetFabric +{ + [DebuggerDisplay("{Revolutions} revolutions")] + [DebuggerTypeProxy(typeof(AngleRevolutionsDebugView))] + [Serializable] + public readonly struct AngleRevolutions + : IEquatable + , IComparable + , IComparable + , IFormattable + { + /// + /// Represents the zero RevolutionsAngle value (0 degrees). This field is read-only. + /// + public static readonly AngleRevolutions Zero = new AngleRevolutions(0.0); + + /// + /// Represents the smallest possible value of a RevolutionsAngle. This field is read-only. + /// + public static readonly AngleRevolutions MinValue = new AngleRevolutions(double.MinValue); + + /// + /// Represents the largest possible value of a RevolutionsAngle. This field is read-only. + /// + public static readonly AngleRevolutions MaxValue = new AngleRevolutions(double.MaxValue); + + /// + /// Represents the right RevolutionsAngle value (90 degrees). This field is read-only. + /// + public static readonly AngleRevolutions Right = new AngleRevolutions(RightAngle); + + /// + /// Represents the straight RevolutionsAngle value (180 degrees). This field is read-only. + /// + public static readonly AngleRevolutions Straight = new AngleRevolutions(StraightAngle); + + /// + /// Represents the full RevolutionsAngle value (360 degrees). This field is read-only. + /// + public static readonly AngleRevolutions Full = new AngleRevolutions(FullAngle); + + /// + /// Gets the amplitude of the angle degrees. This field is read-only. + /// + public readonly double Revolutions; + + internal AngleRevolutions(double degrees) + { + Revolutions = degrees; + } + + #region equality implementation + + /// + /// Indicates whether two RevolutionsAngle instances are equal. + /// + /// The first angle to compare. + /// The second angle to compare. + /// true if the values of a1 and a2 are equal; otherwise, false. + [Pure] + public static bool operator ==(AngleRevolutions a1, AngleRevolutions a2) => + a1.Revolutions == a2.Revolutions; + + /// + /// Indicates whether two RevolutionsAngle instances are equal. + /// + /// The first angle to compare. + /// The second angle to compare. + /// true if the values of a1 and a2 are equal; otherwise, false. + [Pure] + public static bool operator !=(AngleRevolutions a1, AngleRevolutions a2) => + a1.Revolutions != a2.Revolutions; + + /// + /// Indicates whether two RevolutionsAngle instances are equal. + /// + /// The first angle to compare. + /// The second angle to compare. + /// true if the values of a1 and a2 are equal; otherwise, false. + [Pure] + public static bool Equals(AngleRevolutions a1, AngleRevolutions a2) => + a1.Revolutions == a2.Revolutions; + + /// + /// Indicates whether whether this instance is equal to a specified RevolutionsAngle object. + /// + /// An RevolutionsAngle to compare with this instance. + /// true if obj represents the same angle as this instance; otherwise, false. + /// This method implements the System.IEquatable<T> interface, and performs slightly better than because it does not have to convert the obj parameter to an object. + [Pure] + public readonly bool Equals(AngleRevolutions other) => + Revolutions == other.Revolutions; + + #endregion + + #region comparison implementation + + /// + /// Indicates whether a specified RevolutionsAngle is less than another specified RevolutionsAngle. + /// + /// The first angle to compare. + /// The second angle to compare. + /// true if the value of a1 is less than the value of a2; otherwise, false. + [Pure] + public static bool operator <(AngleRevolutions a1, AngleRevolutions a2) => + a1.Revolutions < a2.Revolutions; + + /// + /// Indicates whether a specified RevolutionsAngle is less than or equal to another specified RevolutionsAngle. + /// + /// The first angle to compare. + /// The second angle to compare. + /// true if the value of a1 is less than or equal to the value of a2; otherwise, false. + [Pure] + public static bool operator <=(AngleRevolutions a1, AngleRevolutions a2) => + a1.Revolutions <= a2.Revolutions; + + /// + /// Indicates whether a specified RevolutionsAngle is greater than another specified RevolutionsAngle. + /// + /// The first angle to compare. + /// The second angle to compare. + /// true if the value of a1 is greater than the value of a2; otherwise, false. + [Pure] + public static bool operator >(AngleRevolutions a1, AngleRevolutions a2) => + a1.Revolutions > a2.Revolutions; + + /// + /// Indicates whether a specified RevolutionsAngle is greater than or equal to another specified RevolutionsAngle. + /// + /// The first angle to compare. + /// The second angle to compare. + /// true if the value of a1 is greater than or equal to the value of a2; otherwise, false. + [Pure] + public static bool operator >=(AngleRevolutions a1, AngleRevolutions a2) => + a1.Revolutions >= a2.Revolutions; + + [Pure] + readonly int IComparable.CompareTo(AngleRevolutions other) => + Revolutions.CompareTo(other.Revolutions); + + [Pure] + readonly int IComparable.CompareTo(object obj) + => obj switch + { + AngleRevolutions angle => Revolutions.CompareTo(angle.Revolutions), + _ => Throw.ArgumentException($"Argument has to be an {nameof(AngleRevolutions)}.", nameof(obj)), + }; + + #endregion + + #region math operators + + /// + /// Negates an angle. + /// + /// Source angle. + /// Result of the negation. + [Pure] + public static AngleRevolutions operator -(AngleRevolutions angle) => + new AngleRevolutions(-angle.Revolutions); + + /// + /// Adds two vectors. + /// + /// Source angle. + /// Source angle. + /// Result of the addition. + [Pure] + public static AngleRevolutions operator +(AngleRevolutions left, AngleRevolutions right) => + new AngleRevolutions(left.Revolutions + right.Revolutions); + + /// + /// Subtracts a angle from a angle. + /// + /// Source angle. + /// Source angle. + /// Result of the subtraction. + [Pure] + public static AngleRevolutions operator -(AngleRevolutions left, AngleRevolutions right) => + new AngleRevolutions(left.Revolutions - right.Revolutions); + + /// + /// Multiplies a scalar by an angle value. + /// + /// Scalar value. + /// Source angle. + /// Result of the multiplication. + [Pure] + public static AngleRevolutions operator *(double left, AngleRevolutions right) => + new AngleRevolutions(left * right.Revolutions); + + /// + /// Divides a angle by a scalar value. + /// + /// Source angle. + /// Scalar value. + /// Result of the division. + [Pure] + public static AngleRevolutions operator /(AngleRevolutions left, double right) => + new AngleRevolutions(left.Revolutions / right); + + #endregion + + #region string format + + /// + /// Converts the value of the current RevolutionsAngle object to its equivalent string representation, using a specified format. + /// + /// A string that specifies the format to be used for the returned string. + /// A string representation of the value of the current RevolutionsAngle object, the specified format. + [Pure] + public readonly string ToString(string format) => + Revolutions.ToString(format); + + /// + /// Converts the value of the current RevolutionsAngle object to its equivalent string representation using the specified format and culture-specific format information. + /// + /// A standard or custom date and time format string. + /// An object that supplies culture-specific formatting information. + /// A string representation of value of the current RevolutionsAngle object as specified by format and provider. + [Pure] + public readonly string ToString(string format, IFormatProvider formatProvider) => + Revolutions.ToString(format, formatProvider); + + #endregion + + #region object overrides + + /// + /// Returns a value indicating whether this instance is equal to a specified object. + /// + /// An object to compare with this instance. + /// true if value is a RevolutionsAngle object that represents the same angle as the current RevolutionsAngle structure; otherwise, false. + [Pure] + public override readonly bool Equals(object obj) + => obj switch + { + AngleRevolutions angle => Equals(angle), + _ => false, + }; + + /// + /// Returns a hash code for this instance. + /// + /// A 32-bit signed integer hash code. + [Pure] + public override readonly int GetHashCode() => + Revolutions.GetHashCode(); + + /// + /// Returns a string that represents the current object. + /// + /// A string that represents the current object. + [Pure] + public override readonly string ToString() => + Revolutions.ToString(); + + #endregion + + internal const double RightAngle = 0.25; + internal const double StraightAngle = 0.5; + internal const double FullAngle = 1.0; + + internal static double Reduce(double degrees) => + Utils.Reduce(degrees, FullAngle); + + internal static Quadrant GetQuadrant(double degrees) => + Utils.GetQuadrant(degrees, RightAngle, StraightAngle, FullAngle); + + internal static double GetReference(double degrees) => + Utils.GetReference(degrees, RightAngle, StraightAngle, FullAngle); + + } + + public static partial class Angle + { + /// + /// Returns an RevolutionssAngle that represents a specified number of revolutions. + /// + /// A number of revolutions. + /// An object that represents value. + [Pure] + public static AngleRevolutions FromRevolutions(double value) => + new AngleRevolutions(value); + + /// + /// Returns the absolute value of the RevolutionsAngle. + /// + /// Source angle. + /// + /// An RevolutionsAngle, x, such that RevolutionsAngle.Zero <= x <= RevolutionsAngle.MaxValue. + /// + [Pure] + public static AngleRevolutions Abs(AngleRevolutions angle) => + new AngleRevolutions(Math.Abs(angle.Revolutions)); + + /// + /// Returns a value indicating the sign of an angle. + /// + /// Source angle. + /// A number that indicates the sign of value, -1 if value is less than zero, 0 if value equal to zero, 1 if value is grater than zero. + [Pure] + public static int Sign(AngleRevolutions angle) => + Math.Sign(angle.Revolutions); + + #region min + + /// + /// Returns the smaller of two angles. + /// + /// The first of two angles to compare. + /// The second of two angles to compare. + /// A reference to parameter left or right, whichever is smaller. + [Pure] + public static AngleRevolutions Min(AngleRevolutions left, AngleRevolutions right) + { + if (left.Revolutions < right.Revolutions) + return left; + + return right; + } + + #endregion + + #region max + + /// + /// Returns the largest of two angles. + /// + /// The first of two angles to compare. + /// The second of two angles to compare. + /// A reference to parameter left or right, whichever is larger. + [Pure] + public static AngleRevolutions Max(AngleRevolutions left, AngleRevolutions right) + { + if (left.Revolutions > right.Revolutions) + return left; + + return right; + } + + #endregion + + #region reduce + + /// + /// Reduce an angle between 0 and 2π. + /// + /// Source angle. + /// + [Pure] + public static AngleRevolutions Reduce(AngleRevolutions angle) => + new AngleRevolutions(AngleRevolutions.Reduce(angle.Revolutions)); + + /// + /// Returns the quadrant where the terminal side of the angle is when the standard position. + /// + /// Source angle. + /// The quadrant where the terminal side of the angle is when the standard position. + [Pure] + public static Quadrant GetQuadrant(AngleRevolutions angle) => + AngleRevolutions.GetQuadrant(angle.Revolutions); + + /// + /// Returns the reference angle. + /// + /// Source angle. + /// The reference angle. + [Pure] + public static AngleRevolutions GetReference(AngleRevolutions angle) => + new AngleRevolutions(AngleRevolutions.GetReference(angle.Revolutions)); + + #endregion + + #region comparison + + /// + /// Compares two RevolutionsAngle values and returns an integer that indicates whether the first value is shorter than, equal to, or longer than the second value. + /// + /// The first angle to compare. + /// The second angle to compare. + /// + [Pure] + public static int Compare(AngleRevolutions a1, AngleRevolutions a2) => + a1.Revolutions.CompareTo(a2.Revolutions); + + /// + /// Compares two RevolutionsAngle values and returns an integer that indicates whether when both reduced the first value is shorter than, equal to, or longer than the second value. + /// + /// The first angle to compare. + /// The second angle to compare. + /// + [Pure] + public static int CompareReduced(AngleRevolutions a1, AngleRevolutions a2) => + AngleRevolutions.Reduce(a1.Revolutions).CompareTo(AngleRevolutions.Reduce(a2.Revolutions)); + + #endregion + + #region types of angles + + /// + /// Indicates whether the specified angle is equal to Zero when reduced. + /// + /// Source angle. + /// true if the reduction of the absolute angle is zero; otherwise false. + [Pure] + public static bool IsZero(AngleRevolutions angle) => + angle.Revolutions % AngleRevolutions.FullAngle == 0.0; + + /// + /// Indicates whether the specified angle is acute. + /// + /// Source angle. + /// true if the reduction of the absolute angle is greater than zero and less than 90 degrees; otherwise false. + [Pure] + public static bool IsAcute(AngleRevolutions angle) + { + var reduced = AngleRevolutions.Reduce(Math.Abs(angle.Revolutions)); + return reduced > 0.0 && reduced < AngleRevolutions.RightAngle; + } + + /// + /// Indicates whether the specified angle is right. + /// + /// Source angle. + /// true if the reduction of the absolute angle is 90 degrees; otherwise false. + [Pure] + public static bool IsRight(AngleRevolutions angle) => + AngleRevolutions.Reduce(Math.Abs(angle.Revolutions)) == AngleRevolutions.RightAngle; + + /// + /// Indicates whether the specified angle is obtuse. + /// + /// Source angle. + /// true if the reduction of the absolute angle is greater than 90 degrees and less than 180 degrees; otherwise false. + [Pure] + public static bool IsObtuse(AngleRevolutions angle) + { + var reduced = AngleRevolutions.Reduce(Math.Abs(angle.Revolutions)); + return reduced > AngleRevolutions.RightAngle && reduced < AngleRevolutions.StraightAngle; + } + + /// + /// Indicates whether the specified angle is straight. + /// + /// Source angle. + /// true if the reduction of the absolute angle is 180 degrees; otherwise false. + [Pure] + public static bool IsStraight(AngleRevolutions angle) => + AngleRevolutions.Reduce(Math.Abs(angle.Revolutions)) == AngleRevolutions.StraightAngle; + + /// + /// Indicates whether the specified angle is reflex. + /// + /// Source angle. + /// true if the reduction of the absolute angle is greater than 180 degrees and less than 360 degrees; otherwise false. + [Pure] + public static bool IsReflex(AngleRevolutions angle) => + AngleRevolutions.Reduce(Math.Abs(angle.Revolutions)) > AngleRevolutions.StraightAngle; + + /// + /// Indicates whether the specified angle is oblique. + /// + /// Source angle. + /// true if the angle is not right or a multiple of a right angle; otherwise false. + [Pure] + public static bool IsOblique(AngleRevolutions angle) => + angle.Revolutions % AngleRevolutions.RightAngle != 0.0; + + #endregion + + #region lerp + + /// + /// Performs a linear interpolation. + /// + /// The first angle. + /// The second angle. + /// A value that linearly interpolates between the a1 parameter and the a2 parameter. + /// The result of the linear interpolation. + [Pure] + public static AngleRevolutions Lerp(AngleRevolutions a1, AngleRevolutions a2, double t) => + new AngleRevolutions(Utils.Lerp(a1.Revolutions, a2.Revolutions, t)); + + #endregion + + #region negation + + /// + /// Negates an angle. + /// + /// Source angle. + /// Result of the negation. + [Pure] + public static AngleRevolutions Negate(AngleRevolutions angle) => + new AngleRevolutions(-angle.Revolutions); + + #endregion + + #region addition + + /// + /// Adds two vectors. + /// + /// Source angle. + /// Source angle. + /// Result of the addition. + [Pure] + public static AngleRevolutions Add(AngleRevolutions left, AngleRevolutions right) => + new AngleRevolutions(left.Revolutions + right.Revolutions); + + #endregion + + #region subtraction + + /// + /// Subtracts a angle from a angle. + /// + /// Source angle. + /// Source angle. + /// Result of the subtraction. + [Pure] + public static AngleRevolutions Subtract(AngleRevolutions left, AngleRevolutions right) => + new AngleRevolutions(left.Revolutions - right.Revolutions); + + #endregion + + #region multiplication + + /// + /// Multiplies a angle by a scalar value. + /// + /// Scalar value. + /// Source angle. + /// Result of the multiplication. + [Pure] + public static AngleRevolutions Multiply(double left, AngleRevolutions right) => + new AngleRevolutions(left * right.Revolutions); + + #endregion + + #region division + + /// + /// Divides a angle by a scalar value. + /// + /// Source angle. + /// Scalar value. + /// Result of the division. + [Pure] + public static AngleRevolutions Divide(AngleRevolutions left, double right) => + new AngleRevolutions(left.Revolutions / right); + + #endregion + + } +} diff --git a/NetFabric.Angle/Diagnostics/AngleDegreesDebugView.cs b/NetFabric.Angle/Diagnostics/AngleDegreesDebugView.cs index 93a8eaa..13f6ef1 100644 --- a/NetFabric.Angle/Diagnostics/AngleDegreesDebugView.cs +++ b/NetFabric.Angle/Diagnostics/AngleDegreesDebugView.cs @@ -37,5 +37,8 @@ public string DegreesMinutesSeconds public string Gradians => Angle.ToGradians(angle).Gradians.ToString(); + + public string Revolutions + => Angle.ToRevolutions(angle).Revolutions.ToString(); } } \ No newline at end of file diff --git a/NetFabric.Angle/Diagnostics/AngleGradiansDebugView.cs b/NetFabric.Angle/Diagnostics/AngleGradiansDebugView.cs index bef27b6..ffcf4f4 100644 --- a/NetFabric.Angle/Diagnostics/AngleGradiansDebugView.cs +++ b/NetFabric.Angle/Diagnostics/AngleGradiansDebugView.cs @@ -37,5 +37,8 @@ public string DegreesMinutesSeconds public string Gradians => angle.Gradians.ToString(); + + public string Revolutions + => Angle.ToRevolutions(angle).Revolutions.ToString(); } } \ No newline at end of file diff --git a/NetFabric.Angle/Diagnostics/AngleRadiansDebugView.cs b/NetFabric.Angle/Diagnostics/AngleRadiansDebugView.cs index 57d6fbb..6cf28ad 100644 --- a/NetFabric.Angle/Diagnostics/AngleRadiansDebugView.cs +++ b/NetFabric.Angle/Diagnostics/AngleRadiansDebugView.cs @@ -37,5 +37,8 @@ public string DegreesMinutesSeconds public string Gradians => Angle.ToGradians(angle).Gradians.ToString(); + + public string Revolutions + => Angle.ToRevolutions(angle).Revolutions.ToString(); } } \ No newline at end of file diff --git a/NetFabric.Angle/Diagnostics/AngleRevolutionsDebugView.cs b/NetFabric.Angle/Diagnostics/AngleRevolutionsDebugView.cs new file mode 100644 index 0000000..248a80d --- /dev/null +++ b/NetFabric.Angle/Diagnostics/AngleRevolutionsDebugView.cs @@ -0,0 +1,44 @@ +using System; + +namespace NetFabric +{ + public class AngleRevolutionsDebugView + { + readonly AngleRevolutions angle; + + public AngleRevolutionsDebugView(AngleRevolutions angle) + { + this.angle = angle; + } + + public string Radians + => Angle.ToRadians(angle).Radians.ToString(); + + public string Degrees + => $"{Angle.ToDegrees(angle).Degrees}°"; + + public string DegreesMinutes + { + get + { + Angle.ToDegrees(angle).Deconstruct(out var degrees, out var minutes); + return $"{degrees}° {minutes}'"; + } + } + + public string DegreesMinutesSeconds + { + get + { + Angle.ToDegrees(angle).Deconstruct(out var degrees, out var minutes, out var seconds); + return $"{degrees}° {minutes}' {seconds}''"; + } + } + + public string Gradians + => Angle.ToGradians(angle).Gradians.ToString(); + + public string Revolutions + => angle.Revolutions.ToString(); + } +} \ No newline at end of file diff --git a/NetFabric.Angle/NetFabric.Angle.csproj b/NetFabric.Angle/NetFabric.Angle.csproj index 08242a9..798eb5c 100644 --- a/NetFabric.Angle/NetFabric.Angle.csproj +++ b/NetFabric.Angle/NetFabric.Angle.csproj @@ -8,9 +8,9 @@ The explicit declaration of the units in creation and reading methods, reduces the tipical confusion when dealing with angles. Includes conversion, linear interpolation, reduction, reference angle, comparison, classification, trigonometry and algebra operations. - 3.2.0 - 3.2.0.0 - 3.2.0.0 + 3.3.0 + 3.3.0.0 + 3.3.0.0 Copyright © Antão Almada 2016-2019 Antão Almada NetFabric @@ -18,7 +18,7 @@ LICENSE math, numerics, trigonometry - Added debug views. + Added angle representation in revolutions. NetFabric 8.0 @@ -42,11 +42,18 @@ - - - - - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive +