Skip to content

Instantly share code, notes, and snippets.

@MichalBrylka
Created November 29, 2022 08:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MichalBrylka/c614f567c483bc3a4e4ba5df11007366 to your computer and use it in GitHub Desktop.
Save MichalBrylka/c614f567c483bc3a4e4ba5df11007366 to your computer and use it in GitHub Desktop.
Generic Physics
var distances = Enumerable.Range(1, 10).Select(i => new Distance(i)).ToArray();
var sumOfDistances = Sum(distances);
var times = Enumerable.Range(1, 10).Select(i => new Time(i * i)).ToArray();
var velocities = distances.Zip(times).Select(pair => pair.First / pair.Second).ToArray();
static TUnit Sum<TUnit>(IEnumerable<TUnit> units)
where TUnit : IUnit<TUnit>
{
var result = TUnit.AdditiveIdentity;
foreach (var unit in units)
result += unit;
return result;
}
interface IUnit<TUnit> :
IAdditionOperators<TUnit, TUnit, TUnit>,
IAdditiveIdentity<TUnit, TUnit>
where TUnit : IUnit<TUnit>
{
float Value { get; }
string UnitName { get; }
}
readonly struct Distance :
IUnit<Distance>,
IDivisionOperators<Distance, Time, Velocity>,
IDivisionOperators<Distance, Velocity, Time>
{
public float Value { get; }
public Distance(float value) => Value = value;
public string UnitName => "m";
public static Distance AdditiveIdentity => new(0.0f);
public static Distance operator +(Distance left, Distance right) => new(left.Value + right.Value);
public static Velocity operator /(Distance s, Time t) => new(s.Value / t.Value);
public static Time operator /(Distance s, Velocity v) => new(s.Value / v.Value);
public override string? ToString() => $"{Value} {UnitName}";
}
readonly struct Time : IUnit<Time>
{
public float Value { get; }
public Time(float value) => Value = value;
public string UnitName => "s";
public static Time AdditiveIdentity => new(0.0f);
public static Time operator +(Time left, Time right) => new(left.Value + right.Value);
public override string? ToString() => $"{Value} {UnitName}";
}
readonly struct Velocity :
IUnit<Velocity>,
IMultiplyOperators<Velocity, Time, Distance>
{
public float Value { get; }
public Velocity(float value) => Value = value;
public string UnitName => "m/s";
public static Velocity AdditiveIdentity => new(0.0f);
public static Velocity operator +(Velocity left, Velocity right) => new(left.Value + right.Value);
public static Distance operator *(Velocity v, Time t) => new(v.Value * t.Value);
public override string? ToString() => $"{Value} {UnitName}";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment