Skip to content

Instantly share code, notes, and snippets.

@BrianMacIntosh
Last active August 9, 2017 16:49
Show Gist options
  • Save BrianMacIntosh/dbc2689a544cc4782a84616f10d6b45f to your computer and use it in GitHub Desktop.
Save BrianMacIntosh/dbc2689a544cc4782a84616f10d6b45f to your computer and use it in GitHub Desktop.
Shows how type-safe, automatically-converted degree and radian types could be created in C#.
using System;
class Program
{
static void Main(string[] args)
{
AngleDegrees angleA = new AngleDegrees(90);
AngleRadians angleB = new AngleRadians(Math.PI / 2);
// angleA will be implicitly converted to AngleRadians because that's what the method parameter is
double sinD = Sin(angleA);
Console.WriteLine(sinD);
// angleB is already in radians
double sinR = Sin(angleB);
Console.WriteLine(sinR);
// the return value will be implicitly converted to AngleDegrees
AngleDegrees asinD = Asin(0.5);
Console.WriteLine(asinD);
// the return value is already in radians
AngleRadians asinR = Asin(0.5);
Console.WriteLine(asinR);
// wait to exit
Console.ReadLine();
}
public static double Sin(AngleRadians angle)
{
return Math.Sin(angle.Value);
}
public static AngleRadians Asin(double value)
{
return new AngleRadians(Math.Asin(value));
}
/// <summary>
/// Structure representing an angle in degrees.
/// </summary>
public struct AngleDegrees
{
public double Value;
public AngleDegrees(double angle)
{
Value = angle;
}
/// <summary>
/// Converts this angle to radians.
/// </summary>
public AngleRadians ToRadians()
{
return new AngleRadians(Value * Math.PI / 180f);
}
// Define an implicit conversion from AngleDegrees to AngleRadians.
public static implicit operator AngleRadians(AngleDegrees angle)
{
return angle.ToRadians();
}
// Define math operators on this object
// Yeah, this part's a bit of a pain unfortunately
// We could also do comparison operators
public static AngleDegrees operator *(AngleDegrees a, double b)
{
return new AngleDegrees(a.Value * b);
}
public static AngleDegrees operator /(AngleDegrees a, double b)
{
return new AngleDegrees(a.Value / b);
}
// no implicit addition/subtraction with unidentified doubles
public static AngleDegrees operator *(double a, AngleDegrees b)
{
return new AngleDegrees(a * b.Value);
}
public static AngleDegrees operator /(double a, AngleDegrees b)
{
return new AngleDegrees(a / b.Value);
}
// no implicit addition/subtraction with unidentified doubles
public static AngleDegrees operator *(AngleDegrees a, AngleDegrees b)
{
return new AngleDegrees(a.Value * b.Value);
}
public static AngleDegrees operator /(AngleDegrees a, AngleDegrees b)
{
return new AngleDegrees(a.Value / b.Value);
}
public static AngleDegrees operator +(AngleDegrees a, AngleDegrees b)
{
return new AngleDegrees(a.Value + b.Value);
}
public static AngleDegrees operator -(AngleDegrees a, AngleDegrees b)
{
return new AngleDegrees(a.Value - b.Value);
}
// can do math with radian and degree objects and have them automatically converted
public static AngleDegrees operator *(AngleDegrees a, AngleRadians b)
{
return a * b.ToDegrees();
}
public static AngleDegrees operator /(AngleDegrees a, AngleRadians b)
{
return a.Value / b.ToDegrees();
}
public static AngleDegrees operator +(AngleDegrees a, AngleRadians b)
{
return a.Value + b.ToDegrees();
}
public static AngleDegrees operator -(AngleDegrees a, AngleRadians b)
{
return a.Value - b.ToDegrees();
}
// can override how this value is converted to a string, too
public override string ToString()
{
// add the degree sign
return Value + "\u00B0";
}
}
/// <summary>
/// Structure representing an angle in radians.
/// </summary>
public struct AngleRadians
{
public double Value;
public AngleRadians(double angle)
{
Value = angle;
}
/// <summary>
/// Converts this angle to degrees.
/// </summary>
public AngleDegrees ToDegrees()
{
return new AngleDegrees(Value * 180f / Math.PI);
}
// Define an implicit conversion from AngleRadians to AngleDegrees.
public static implicit operator AngleDegrees(AngleRadians angle)
{
return angle.ToDegrees();
}
// Define math operators on this object
// Yeah, this part's a bit of a pain unfortunately
// We could also do comparison operators
public static AngleRadians operator *(AngleRadians a, double b)
{
return new AngleRadians(a.Value * b);
}
public static AngleRadians operator /(AngleRadians a, double b)
{
return new AngleRadians(a.Value / b);
}
// no implicit addition/subtraction with unidentified doubles
public static AngleRadians operator *(double a, AngleRadians b)
{
return new AngleRadians(a * b.Value);
}
public static AngleRadians operator /(double a, AngleRadians b)
{
return new AngleRadians(a / b.Value);
}
// no implicit addition/subtraction with unidentified doubles
public static AngleRadians operator *(AngleRadians a, AngleRadians b)
{
return new AngleRadians(a.Value * b.Value);
}
public static AngleRadians operator /(AngleRadians a, AngleRadians b)
{
return new AngleRadians(a.Value / b.Value);
}
public static AngleRadians operator +(AngleRadians a, AngleRadians b)
{
return new AngleRadians(a.Value + b.Value);
}
public static AngleRadians operator -(AngleRadians a, AngleRadians b)
{
return new AngleRadians(a.Value - b.Value);
}
public static AngleRadians operator *(AngleRadians a, AngleDegrees b)
{
return a * b.ToRadians();
}
public static AngleRadians operator /(AngleRadians a, AngleDegrees b)
{
return a / b.ToRadians();
}
public static AngleRadians operator +(AngleRadians a, AngleDegrees b)
{
return a + b.ToRadians();
}
public static AngleRadians operator -(AngleRadians a, AngleDegrees b)
{
return a - b.ToRadians();
}
// can override how this value is converted to a string, too
public override string ToString()
{
// show it as a multiple of Pi since that's easier to understand
return (Value / Math.PI) + "\u03C0";
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment