Last active
August 16, 2017 21:29
-
-
Save JohanLarsson/69cb351cf859be6562d8a1c095129f0b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Meh | |
{ | |
using System; | |
using System.ComponentModel; | |
using System.Globalization; | |
using System.Text.RegularExpressions; | |
using System.Windows; | |
public struct Angle : IEquatable<Angle> | |
{ | |
public const double DegToRad = Math.PI / 180; | |
public const double RadToDeg = 180 / Math.PI; | |
private Angle(double degrees) | |
{ | |
this.Degrees = degrees; | |
} | |
public static Angle Zero { get; } = new Angle(0); | |
public double Degrees { get; } | |
public double Radians => DegToRad * this.Degrees; | |
public static Angle operator +(Angle left, Angle right) | |
{ | |
return new Angle(left.Degrees + right.Degrees); | |
} | |
public static Angle operator -(Angle left, Angle right) | |
{ | |
return new Angle(left.Degrees - right.Degrees); | |
} | |
/// <summary> | |
/// Returns an <see cref="Angle"/> whose quantity is the negated quantity of the specified instance. | |
/// </summary> | |
/// <returns> | |
/// An <see cref="Angle"/> with the same numeric quantity as this instance, but the opposite sign. | |
/// </returns> | |
/// <param name="angle">An instance of <see cref="Angle"/></param> | |
public static Angle operator -(Angle angle) | |
{ | |
return new Angle(-angle.Degrees); | |
} | |
public static Angle operator *(double left, Angle right) | |
{ | |
return new Angle(left * right.Degrees); | |
} | |
public static Angle operator /(Angle left, double right) | |
{ | |
return new Angle(left.Degrees / right); | |
} | |
public static bool operator ==(Angle left, Angle right) | |
{ | |
return left.Equals(right); | |
} | |
public static bool operator !=(Angle left, Angle right) | |
{ | |
return !left.Equals(right); | |
} | |
/// <summary> | |
/// Indicates whether a specified <see cref="Angle"/> is less than another specified <see cref="Angle"/>. | |
/// </summary> | |
/// <returns> | |
/// true if the quantity of <paramref name="left"/> is less than the quantity of <paramref name="right"/>; otherwise, false. | |
/// </returns> | |
/// <param name="left">The left instance of <see cref="Angle"/>.</param> | |
/// <param name="right">The right instance of <see cref="Angle"/>.</param> | |
public static bool operator <(Angle left, Angle right) | |
{ | |
return left.Degrees < right.Degrees; | |
} | |
/// <summary> | |
/// Indicates whether a specified <see cref="Angle"/> is greater than another specified <see cref="Angle"/>. | |
/// </summary> | |
/// <returns> | |
/// true if the quantity of <paramref name="left"/> is greater than the quantity of <paramref name="right"/>; otherwise, false. | |
/// </returns> | |
/// <param name="left">The left instance of <see cref="Angle"/>.</param> | |
/// <param name="right">The right instance of <see cref="Angle"/>.</param> | |
public static bool operator >(Angle left, Angle right) | |
{ | |
return left.Degrees > right.Degrees; | |
} | |
/// <summary> | |
/// Indicates whether a specified <see cref="Angle"/> is less than or equal to another specified <see cref="Angle"/>. | |
/// </summary> | |
/// <returns> | |
/// true if the quantity of <paramref name="left"/> is less than or equal to the quantity of <paramref name="right"/>; otherwise, false. | |
/// </returns> | |
/// <param name="left">The left instance of <see cref="Angle"/>.</param> | |
/// <param name="right">The right instance of <see cref="Angle"/>.</param> | |
public static bool operator <=(Angle left, Angle right) | |
{ | |
return left.Degrees <= right.Degrees; | |
} | |
/// <summary> | |
/// Indicates whether a specified <see cref="Angle"/> is greater than or equal to another specified <see cref="Angle"/>. | |
/// </summary> | |
/// <returns> | |
/// true if the quantity of <paramref name="left"/> is greater than or equal to the quantity of <paramref name="right"/>; otherwise, false. | |
/// </returns> | |
/// <param name="left">The left instance of <see cref="Angle"/>.</param> | |
/// <param name="right">The right instance of <see cref="Angle"/>.</param> | |
public static bool operator >=(Angle left, Angle right) | |
{ | |
return left.Degrees >= right.Degrees; | |
} | |
public static Angle FromDegrees(double value) => new Angle(value); | |
public static Angle FromRadians(double radians) | |
{ | |
return new Angle(RadToDeg * radians); | |
} | |
public static Angle Parse(string text) | |
{ | |
if (TryParse(text, out Angle angle)) | |
{ | |
return angle; | |
} | |
throw new FormatException($"Could not parse an angle from {text}"); | |
} | |
public static bool TryParse(string text, out Angle angle) | |
{ | |
if (double.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out double d1)) | |
{ | |
angle = FromDegrees(d1); | |
return true; | |
} | |
var match = Regex.Match(text, "(?<number>.+) ?(°|deg|degrees)", RegexOptions.IgnoreCase | RegexOptions.RightToLeft); | |
if (match.Success) | |
{ | |
return TryParse(match.Groups["number"].Value, out angle); | |
} | |
match = Regex.Match(text, "(?<number>.+) ?(rad|radians)", RegexOptions.IgnoreCase | RegexOptions.RightToLeft); | |
if (match.Success && | |
double.TryParse( | |
match.Groups["number"].Value, | |
NumberStyles.Float, | |
CultureInfo.InvariantCulture, | |
out double d3)) | |
{ | |
angle = FromRadians(d3); | |
return true; | |
} | |
angle = default(Angle); | |
return false; | |
} | |
public bool Equals(Angle other) | |
{ | |
return DoubleUtil.AreClose(this, other); | |
} | |
public override bool Equals(object obj) | |
{ | |
if (ReferenceEquals(null, obj)) | |
{ | |
return false; | |
} | |
return obj is Angle && this.Equals((Angle)obj); | |
} | |
public override int GetHashCode() | |
{ | |
return this.Degrees.GetHashCode(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment