/// <summary> /// Simplifies an array of UnitPowerPairs so it contains only one instance of each unit /// </summary> /// <param name="units">The array of pairs to simplify</param> /// <returns>A simplified array of UnitPowerPairs</returns> public static UnitPowerPair[] SimplifyUnits(UnitPowerPair[] units) { List <UnitPowerPair> newUnits = new List <UnitPowerPair>(); foreach (UnitPowerPair pair in units) { if (newUnits.Count == 0) { newUnits.Add(pair); } else { bool added = false; for (int i = 0; i < newUnits.Count; i++) { if (newUnits[i].Unit == pair.Unit) { newUnits[i] = new UnitPowerPair { Unit = newUnits[i].Unit, Power = newUnits[i].Power + pair.Power }; added = true; break; } } if (!added) { newUnits.Add(pair); } } } // Remove all units with a power of 0 bool isTarget(UnitPowerPair pair) { return(pair.Power == 0); } newUnits.RemoveAll(new Predicate <UnitPowerPair>(isTarget)); if (newUnits.Count == 0) { newUnits.Add(new UnitPowerPair { Unit = Units.NoUnit, Power = 0 }); } else if (newUnits.Count > 1) { bool isTarget2(UnitPowerPair pair) { return(pair.Unit == Units.NoUnit); } newUnits.RemoveAll(new Predicate <UnitPowerPair>(isTarget2)); } return(newUnits.ToArray()); }
/// <summary> /// Gets the conversion multiplier applied to the current value needed to associate the value with a different unit /// </summary> /// <param name="currentUnit">The current units</param> /// <param name="newUnit">The units to convert to</param> /// <returns>A multiplier as a double. current * multiplier = new</returns> public static double GetUnitConversion(IGeneralUnit currentUnit, IGeneralUnit newUnit) { double conversion = 1; CompoundUnit currentCompound = new CompoundUnit(currentUnit); CompoundUnit newCompound = new CompoundUnit(newUnit); List <UnitPowerPair> currentValues = currentCompound.Values.OrderBy(new Func <UnitPowerPair, Quantities>((UnitPowerPair pair) => pair.Unit.GetQuantity())).ToList(); List <UnitPowerPair> newValues = newCompound.Values.OrderBy(new Func <UnitPowerPair, Quantities>((UnitPowerPair pair) => pair.Unit.GetQuantity())).ToList(); if (currentValues.Count == newValues.Count) { for (int i = 0; i < currentValues.Count; i++) { if (currentValues[i].Power == newValues[i].Power) { conversion *= Math.Pow(GetUnitConversion(currentValues[i].Unit, newValues[i].Unit), currentValues[i].Power); } else { // The units have different powers and therfore aren't convertable throw new ArgumentException("Unit conversion failed - the units provided had different powers so they don't represent the same physical quantity and therfore can't be converted."); } } } else { // Pre convert all units to their system's base unit for (int i = 0; i < currentValues.Count; i++) { Units preConvertedUnit = currentValues[i].Unit.GetQuantity().GetSystemBaseUnit(currentValues[i].Unit.GetSystem()); conversion *= Math.Pow(GetUnitConversion(currentValues[i].Unit, preConvertedUnit), currentValues[i].Power); currentValues[i] = new UnitPowerPair { Unit = preConvertedUnit, Power = currentValues[i].Power }; } for (int i = 0; i < newValues.Count; i++) { Units preConvertedUnit = newValues[i].Unit.GetQuantity().GetSystemBaseUnit(newValues[i].Unit.GetSystem()); conversion *= Math.Pow(GetUnitConversion(newValues[i].Unit, preConvertedUnit), newValues[i].Power); newValues[i] = new UnitPowerPair { Unit = preConvertedUnit, Power = newValues[i].Power }; } conversion *= GetUnitConversion(new CompoundUnit(currentValues.ToArray()), new CompoundUnit(newValues.ToArray())); } return(conversion); }
/// <summary> /// Raises a unit to a power /// </summary> /// <param name="p">The power</param> /// <returns>A new IGeneralUnit instance</returns> public IGeneralUnit Pow(int p) { UnitPowerPair[] newValues = new UnitPowerPair[Values.Length]; for (int i = 0; i < Values.Length; i++) { newValues[i] = new UnitPowerPair { Unit = Values[i].Unit, Power = Values[i].Power * p }; } return(new CompoundUnit(newValues)); }
/// <summary> /// Creates a new compound unit from an array of tuples containing units and their corisponding powers /// </summary> /// <param name="units">Array of units and their powers as Tuples</param> public CompoundUnit(params Tuple <Units, int>[] units) { Values = new UnitPowerPair[units.Length]; for (int i = 0; i < units.Length; i++) { Values[i] = new UnitPowerPair { Unit = units[i].Item1, Power = units[i].Item2 }; } Values = SimplifyUnits(Values); }