Skip to content

Commit ce7030d

Browse files
committed
Merge remote-tracking branch 'gpetrou/Angles'
2 parents a40e25b + 17b5640 commit ce7030d

File tree

8 files changed

+328
-0
lines changed

8 files changed

+328
-0
lines changed

Src/UnitsNet/Angle.cs

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
using System;
2+
3+
namespace UnitsNet
4+
{
5+
public struct Angle : IComparable, IComparable<Angle>
6+
{
7+
private const double RadiansToDegreesRatio = Math.PI / 180.0;
8+
private const double GradiansToDegreesRatio = 1 / 0.9;
9+
10+
public readonly double Degrees;
11+
12+
public Angle(double degrees)
13+
{
14+
Degrees = degrees;
15+
}
16+
17+
#region Unit Properties
18+
19+
public double Radians
20+
{
21+
get { return Degrees * RadiansToDegreesRatio; }
22+
}
23+
24+
public double Gradians
25+
{
26+
get { return Degrees * GradiansToDegreesRatio; }
27+
}
28+
29+
#endregion
30+
31+
#region Static
32+
33+
public static Angle Zero
34+
{
35+
get { return new Angle(0); }
36+
}
37+
38+
public static Angle FromDegrees(double degrees)
39+
{
40+
return new Angle(degrees);
41+
}
42+
43+
public static Angle FromRadians(double radians)
44+
{
45+
return new Angle(radians / RadiansToDegreesRatio);
46+
}
47+
48+
public static Angle FromGradians(double gradians)
49+
{
50+
return new Angle(gradians / GradiansToDegreesRatio);
51+
}
52+
53+
#endregion
54+
55+
#region Arithmetic operators
56+
57+
public static Angle operator -(Angle right)
58+
{
59+
return FromDegrees(-right.Degrees);
60+
}
61+
62+
public static Angle operator +(Angle left, Angle right)
63+
{
64+
return FromDegrees(left.Degrees + right.Degrees);
65+
}
66+
67+
public static Angle operator -(Angle left, Angle right)
68+
{
69+
return FromDegrees(left.Degrees - right.Degrees);
70+
}
71+
72+
public static Angle operator *(double left, Angle right)
73+
{
74+
return FromDegrees(left * right.Degrees);
75+
}
76+
77+
public static Angle operator *(Angle left, double right)
78+
{
79+
return FromDegrees(left.Degrees * right);
80+
}
81+
82+
public static Angle operator /(Angle left, double right)
83+
{
84+
return FromDegrees(left.Degrees / right);
85+
}
86+
87+
public static double operator /(Angle left, Angle right)
88+
{
89+
return left.Degrees / right.Degrees;
90+
}
91+
92+
#endregion
93+
94+
#region Comparable operators
95+
96+
public static bool operator <=(Angle left, Angle right)
97+
{
98+
return left.Degrees <= right.Degrees;
99+
}
100+
101+
public static bool operator >=(Angle left, Angle right)
102+
{
103+
return left.Degrees >= right.Degrees;
104+
}
105+
106+
public static bool operator <(Angle left, Angle right)
107+
{
108+
return left.Degrees < right.Degrees;
109+
}
110+
111+
public static bool operator >(Angle left, Angle right)
112+
{
113+
return left.Degrees > right.Degrees;
114+
}
115+
116+
public static bool operator ==(Angle left, Angle right)
117+
{
118+
return left.Degrees == right.Degrees;
119+
}
120+
121+
public static bool operator !=(Angle left, Angle right)
122+
{
123+
return !(left.Degrees == right.Degrees);
124+
}
125+
126+
#endregion
127+
128+
#region Equality / IComparable
129+
130+
public int CompareTo(object obj)
131+
{
132+
if (obj == null) throw new ArgumentNullException("obj");
133+
if (!(obj is Angle)) throw new ArgumentException("Expected type Angle.", "obj");
134+
return CompareTo((Angle)obj);
135+
}
136+
137+
public int CompareTo(Angle other)
138+
{
139+
return Degrees.CompareTo(other.Degrees);
140+
}
141+
142+
public override bool Equals(object obj)
143+
{
144+
if (obj == null || !(obj is Angle))
145+
{
146+
return false;
147+
}
148+
149+
return Degrees.CompareTo(((Angle)obj).Degrees) == 0;
150+
}
151+
152+
public override int GetHashCode()
153+
{
154+
return base.GetHashCode();
155+
}
156+
157+
#endregion
158+
159+
public override string ToString()
160+
{
161+
return Degrees + " °";
162+
}
163+
}
164+
}

Src/UnitsNet/Unit.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ public enum Unit
103103
SquareFoot,
104104
SquareInch,
105105

106+
// Angle
107+
Degree,
108+
Radian,
109+
Gradian,
110+
106111
// Volume
107112
CubicKilometer,
108113
CubicMeter,

Src/UnitsNet/UnitConverter.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public static double Convert(double value, Unit fromUnit, Unit toUnit)
4444
double newValue;
4545
if (TryConvertLength(value, fromUnit, toUnit, out newValue)) return newValue;
4646
if (TryConvertArea(value, fromUnit, toUnit, out newValue)) return newValue;
47+
if (TryConvertAngle(value, fromUnit, toUnit, out newValue)) return newValue;
4748
if (TryConvertVolume(value, fromUnit, toUnit, out newValue)) return newValue;
4849
if (TryConvertMass(value, fromUnit, toUnit, out newValue)) return newValue;
4950
if (TryConvertPressure(value, fromUnit, toUnit, out newValue)) return newValue;
@@ -74,6 +75,8 @@ public static bool TryConvert(double value, Unit fromUnit, Unit toUnit, out doub
7475
}
7576

7677
if (TryConvertLength(value, fromUnit, toUnit, out newValue)) return true;
78+
if (TryConvertArea(value, fromUnit, toUnit, out newValue)) return true;
79+
if (TryConvertAngle(value, fromUnit, toUnit, out newValue)) return true;
7780
if (TryConvertVolume(value, fromUnit, toUnit, out newValue)) return true;
7881
if (TryConvertMass(value, fromUnit, toUnit, out newValue)) return true;
7982
if (TryConvertPressure(value, fromUnit, toUnit, out newValue)) return true;
@@ -244,6 +247,22 @@ private static bool TryConvertArea(double value, Unit fromUnit, Unit toUnit, out
244247
}
245248
}
246249

250+
private static bool TryConvertAngle(double value, Unit fromUnit, Unit toUnit, out double newValue)
251+
{
252+
switch (fromUnit)
253+
{
254+
case Unit.Degree:
255+
return TryConvert(Angle.FromDegrees(value), toUnit, out newValue);
256+
case Unit.Radian:
257+
return TryConvert(Angle.FromRadians(value), toUnit, out newValue);
258+
case Unit.Gradian:
259+
return TryConvert(Angle.FromGradians(value), toUnit, out newValue);
260+
default:
261+
newValue = 0;
262+
return false;
263+
}
264+
}
265+
247266
private static bool TryConvertVolume(double value, Unit fromUnit, Unit toUnit, out double newValue)
248267
{
249268
switch (fromUnit)
@@ -415,6 +434,25 @@ private static bool TryConvert(Area volume, Unit toUnit, out double newValue)
415434
}
416435
}
417436

437+
private static bool TryConvert(Angle angle, Unit toUnit, out double newValue)
438+
{
439+
switch (toUnit)
440+
{
441+
case Unit.Degree:
442+
newValue = angle.Degrees;
443+
return true;
444+
case Unit.Radian:
445+
newValue = angle.Radians;
446+
return true;
447+
case Unit.Gradian:
448+
newValue = angle.Gradians;
449+
return true;
450+
default:
451+
newValue = 0;
452+
return false;
453+
}
454+
}
455+
418456
private static bool TryConvert(Volume volume, Unit toUnit, out double newValue)
419457
{
420458
switch (toUnit)

Src/UnitsNet/UnitsNet.net35.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
<Reference Include="System.Xml" />
3939
</ItemGroup>
4040
<ItemGroup>
41+
<Compile Include="Angle.cs" />
4142
<Compile Include="Area.cs" />
4243
<Compile Include="ElectricPotential.cs" />
4344
<Compile Include="EnumUtils.cs" />

Src/UnitsNet/UnitsNet.pcl.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
<!-- A reference to the entire .NET Framework is automatically included -->
3636
</ItemGroup>
3737
<ItemGroup>
38+
<Compile Include="Angle.cs" />
3839
<Compile Include="Area.cs" />
3940
<Compile Include="ElectricPotential.cs" />
4041
<Compile Include="EnumUtils.cs" />

Src/UnitsNet/UnitsNet.sl4.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
<Reference Include="System.Windows.Browser" />
5757
</ItemGroup>
5858
<ItemGroup>
59+
<Compile Include="Angle.cs" />
5960
<Compile Include="Area.cs" />
6061
<Compile Include="EnumUtils.cs" />
6162
<Compile Include="Force.cs" />

Tests/AngleTest.cs

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
using System;
2+
using NUnit.Framework;
3+
4+
namespace UnitsNet.Tests.net35
5+
{
6+
[TestFixture]
7+
public class AngleTests
8+
{
9+
private const double Delta = 1E-5;
10+
private readonly Angle _degrees90 = Angle.FromDegrees(90);
11+
12+
[Test]
13+
public void DegreesToAngleUnits()
14+
{
15+
Assert.AreEqual(Math.PI / 2, _degrees90.Radians, Delta);
16+
Assert.AreEqual(100, _degrees90.Gradians, Delta);
17+
}
18+
19+
[Test]
20+
public void AngleUnitsRoundTrip()
21+
{
22+
Assert.AreEqual(90, Angle.FromRadians(_degrees90.Radians).Degrees, Delta);
23+
Assert.AreEqual(90, Angle.FromGradians(_degrees90.Gradians).Degrees, Delta);
24+
}
25+
26+
[Test]
27+
public void ArithmeticOperatorsRoundtrip()
28+
{
29+
Angle a = Angle.FromDegrees(90);
30+
Assert.AreEqual(-90, -a.Degrees, Delta);
31+
Assert.AreEqual(180, (Angle.FromDegrees(270)-a).Degrees, Delta);
32+
Assert.AreEqual(180, (a + a).Degrees, Delta);
33+
Assert.AreEqual(900, (a * 10).Degrees, Delta);
34+
Assert.AreEqual(900, (10 * a).Degrees, Delta);
35+
Assert.AreEqual(18.0, (Angle.FromDegrees(90) / 5).Degrees, Delta);
36+
Assert.AreEqual(18.0, Angle.FromDegrees(90) / Angle.FromDegrees(5), Delta);
37+
}
38+
39+
[Test]
40+
public void ComparisonOperators()
41+
{
42+
Angle degrees90 = Angle.FromDegrees(90);
43+
Angle degrees180 = Angle.FromDegrees(180);
44+
45+
Assert.True(degrees90 < degrees180);
46+
Assert.True(degrees90 <= degrees180);
47+
Assert.True(degrees180 > degrees90);
48+
Assert.True(degrees180 >= degrees90);
49+
50+
Assert.False(degrees90 > degrees180);
51+
Assert.False(degrees90 >= degrees180);
52+
Assert.False(degrees180 < degrees90);
53+
Assert.False(degrees180 <= degrees90);
54+
}
55+
56+
[Test]
57+
public void CompareToIsImplemented()
58+
{
59+
Angle degree = Angle.FromDegrees(1);
60+
Assert.AreEqual(0, degree.CompareTo(degree));
61+
Assert.Greater(degree.CompareTo(Angle.Zero), 0);
62+
Assert.Less(Angle.Zero.CompareTo(degree), 0);
63+
}
64+
65+
[Test]
66+
[ExpectedException(typeof(ArgumentException))]
67+
public void CompareToThrowsOnTypeMismatch()
68+
{
69+
Angle angle = Angle.FromDegrees(90);
70+
angle.CompareTo(new object());
71+
}
72+
73+
[Test]
74+
[ExpectedException(typeof(ArgumentNullException))]
75+
public void CompareToThrowsOnNull()
76+
{
77+
Angle angle = Angle.FromDegrees(90);
78+
angle.CompareTo(null);
79+
}
80+
81+
82+
[Test]
83+
public void EqualityOperators()
84+
{
85+
Angle a = Angle.FromDegrees(90);
86+
Angle b = Angle.FromDegrees(180);
87+
88+
Assert.True(a == a);
89+
Assert.True(a != b);
90+
91+
Assert.False(a == b);
92+
Assert.False(a != a);
93+
}
94+
95+
[Test]
96+
public void EqualsIsImplemented()
97+
{
98+
Angle a = Angle.FromDegrees(90);
99+
Assert.IsTrue(a.Equals(Angle.FromDegrees(90)));
100+
Assert.IsFalse(a.Equals(Angle.Zero));
101+
}
102+
103+
[Test]
104+
public void EqualsReturnsFalseOnTypeMismatch()
105+
{
106+
Angle angle = Angle.FromDegrees(0);
107+
Assert.IsFalse(angle.Equals(new object()));
108+
}
109+
110+
[Test]
111+
public void EqualsReturnsFalseOnNull()
112+
{
113+
Angle angle = Angle.FromDegrees(0);
114+
Assert.IsFalse(angle.Equals(null));
115+
}
116+
}
117+
}

Tests/UnitsNet.Tests.net35.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
<Reference Include="System.Xml" />
4545
</ItemGroup>
4646
<ItemGroup>
47+
<Compile Include="AngleTest.cs" />
4748
<Compile Include="AreaTests.cs" />
4849
<Compile Include="VolumeTests.cs" />
4950
<Compile Include="Length2dTests.cs" />

0 commit comments

Comments
 (0)