001// Copyright (c) FIRST and other WPILib contributors.
002// Open Source Software; you can modify and/or share it under the terms of
003// the WPILib BSD license file in the root directory of this project.
004
005package edu.wpi.first.units;
006
007import edu.wpi.first.units.measure.LinearMomentum;
008
009/** A unit of linear momentum like {@link edu.wpi.first.units.Units#KilogramMetersPerSecond}. */
010public final class LinearMomentumUnit extends MultUnit<MassUnit, LinearVelocityUnit> {
011  private static final CombinatoryUnitCache<MassUnit, LinearVelocityUnit, LinearMomentumUnit>
012      cache = new CombinatoryUnitCache<>(LinearMomentumUnit::new);
013
014  LinearMomentumUnit(MassUnit unit, LinearVelocityUnit linearVelocityUnit) {
015    super(
016        unit.isBaseUnit() && linearVelocityUnit.isBaseUnit()
017            ? null
018            : combine(unit.getBaseUnit(), linearVelocityUnit.getBaseUnit()),
019        unit,
020        linearVelocityUnit);
021  }
022
023  LinearMomentumUnit(
024      MultUnit<MassUnit, LinearVelocityUnit> baseUnit,
025      UnaryFunction toBaseConverter,
026      UnaryFunction fromBaseConverter,
027      String name,
028      String symbol) {
029    super(baseUnit, toBaseConverter, fromBaseConverter, name, symbol);
030  }
031
032  /**
033   * Combines a mass and linear velocity unit to form a combined linear momentum unit.
034   *
035   * @param mass the unit of mass
036   * @param velocity the unit of velocity
037   * @return the combined unit of momentum
038   */
039  public static LinearMomentumUnit combine(MassUnit mass, LinearVelocityUnit velocity) {
040    return cache.combine(mass, velocity);
041  }
042
043  @Override
044  public LinearMomentumUnit getBaseUnit() {
045    return (LinearMomentumUnit) super.getBaseUnit();
046  }
047
048  @Override
049  public LinearMomentum of(double magnitude) {
050    return new LinearMomentum(magnitude, toBaseUnits(magnitude), this);
051  }
052
053  @Override
054  public LinearMomentum ofBaseUnits(double baseUnitMagnitude) {
055    return new LinearMomentum(fromBaseUnits(baseUnitMagnitude), baseUnitMagnitude, this);
056  }
057
058  @Override
059  public LinearMomentum zero() {
060    return (LinearMomentum) super.zero();
061  }
062
063  @Override
064  public LinearMomentum one() {
065    return (LinearMomentum) super.one();
066  }
067
068  @Override
069  public VelocityUnit<LinearMomentumUnit> per(TimeUnit time) {
070    return VelocityUnit.combine(this, time);
071  }
072
073  /**
074   * Creates a ratio unit between this unit and an arbitrary other unit.
075   *
076   * @param other the other unit
077   * @param <U> the type of the other unit
078   * @return the ratio unit
079   */
080  public <U extends Unit> PerUnit<LinearMomentumUnit, U> per(U other) {
081    return PerUnit.combine(this, other);
082  }
083
084  /**
085   * Converts a measurement value in terms of another unit to this unit.
086   *
087   * @param magnitude the magnitude of the measurement in terms of the other unit
088   * @param otherUnit the other unit
089   * @return the value of the measurement in terms of this unit
090   */
091  public double convertFrom(double magnitude, LinearMomentumUnit otherUnit) {
092    return fromBaseUnits(otherUnit.toBaseUnits(magnitude));
093  }
094
095  /**
096   * Multiplies this unit by distance to form a unit of angular momentum.
097   *
098   * @param distance the unit of distance
099   * @return the combined unit of angular momentum
100   */
101  public AngularMomentumUnit mult(DistanceUnit distance) {
102    return AngularMomentumUnit.combine(this, distance);
103  }
104}