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; }
}
}