using System; using Chernobyl.Mathematics.Vectors; using Chernobyl.Measures; using Chernobyl.Measures.Speed; using Chernobyl.Measures.Time; namespace Chernobyl.Mathematics.Measures { /// /// The speed at which an object is moving and in what direction. /// public struct Velocity : IMeasurement, IEquatable { /// /// Initializes a new instance of the struct. /// /// The direction in which an object is moving. /// This will be normalized by this type. /// The speed component of the velocity in metres /// per second. public Velocity(Vector3d direction, Metres speed) : this() { direction.Normalize(); Value = direction * speed.Value; } /// /// Initializes a new instance of the struct. /// /// The direction and speed of the /// velocity expressed as a where the normalized /// vector is the direction and the vector's length is the speed in /// meters per second. public Velocity(Vector3d directionAndSpeed) : this() { Value = directionAndSpeed; } /// /// Performs an implicit conversion from to /// . /// /// The velocity to convert. /// The as a raw . public static implicit operator Vector3d(Velocity velocity) { return velocity.Value; } /// /// Performs an implicit conversion from to /// . /// /// The to convert. /// The as a . public static explicit operator Velocity(Vector3d vector) { return new Velocity(vector); } /// /// Performs an implicit conversion from to /// . /// /// The velocity to convert. /// The in the form of speed. public static explicit operator Metres(Velocity velocity) { return velocity.Speed; } /// /// Adds two instances together. /// /// The left side of the operand. /// The right side of the operand. /// The result of the addition. public static Velocity operator +(Velocity left, Velocity right) { return new Velocity(left.Value + right.Value); } /// /// Subtracts two instances from each other. /// /// The left side of the operand. /// The right side of the operand. /// The result of the negation. public static Velocity operator -(Velocity left, Velocity right) { return new Velocity(left.Value - right.Value); } /// /// Negates a . /// /// The to be negated. /// The result of the multiplication. public static Velocity operator -(Velocity velocity) { return new Velocity(-velocity.Value); } /// /// Multiplies a by a scalar. /// /// The left side of the operand. /// The right side of the operand. /// The result of the multiplication. public static Velocity operator *(Velocity velocity, Metres time) { return new Velocity(velocity.Value * time.Value); } /// /// Multiplies a by a scalar. /// /// The left side of the operand. /// The right side of the operand. /// The result of the multiplication. public static Velocity operator *(Metres time, Velocity velocity) { return new Velocity(time.Value * velocity.Value); } /// /// Divides a by a scalar. /// /// The left side of the operand. /// The right side of the operand. /// The result of the division. public static Velocity operator /(Velocity velocity, Metres time) { return new Velocity(velocity.Value * time.Value); } /// /// Checks if two instances are equal. /// /// The left side of the operand. /// The right side of the operand. /// True if they are equal, false if otherwise. public static bool operator ==(Velocity left, Velocity right) { return left.Equals(right); } /// /// Checks if two instances are not equal. /// /// The left side of the operand. /// The right side of the operand. /// True if they are not equal, false if otherwise. public static bool operator !=(Velocity left, Velocity right) { return !left.Equals(right); } /// /// Gets the hash code of the . /// /// The hash code of the . public override int GetHashCode() { return Value.GetHashCode(); } /// /// Indicates whether the current object is equal to another object of /// the same type. /// /// An object to compare with this object. /// True if the current object is equal to the /// parameter; otherwise, false. /// public bool Equals(Velocity other) { return Value.Equals(other.Value); } /// /// Checks this for equality with object passed in. /// /// The object to compare to. /// True if the object is equal to this , /// false if otherwise. public override bool Equals(object obj) { return (obj is Velocity && Equals((Velocity)obj)); } /// /// Returns a that represents this instance. For /// example, a velocity of (2.4, 22.4, 55.9) will be returned as /// "(0.0398215899277352, 0.371668172658861, 0.927511198733498) at /// 60.2688140869141 m/s". /// /// A that represents this instance. public override string ToString() { return Direction + " at " + Speed; } /// /// The direction in which an object is moving as a normalized (unit) /// vector. /// public Vector3d Direction { get { Vector3d result = Value; result.Normalize(); return result; } } /// /// The speed component of the velocity in metres per second. /// public Metres Speed { get { return (Metres)Value.Length; } } /// /// The raw value of the velocity as a . /// public Vector3d Value { get; private set; } } }