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.MomentOfInertia;
008
009/**
010 * A unit of moment of inertia, like {@link edu.wpi.first.units.Units#KilogramSquareMeters}. Moments
011 * of inertia describe how much an object resists being rotated, analogous to mass's resistance to
012 * being accelerated along a line.
013 */
014public final class MomentOfInertiaUnit extends PerUnit<AngularMomentumUnit, AngularVelocityUnit> {
015  private static final CombinatoryUnitCache<
016          AngularMomentumUnit, AngularVelocityUnit, MomentOfInertiaUnit>
017      cache = new CombinatoryUnitCache<>(MomentOfInertiaUnit::new);
018
019  MomentOfInertiaUnit(AngularMomentumUnit numerator, AngularVelocityUnit denominator) {
020    super(
021        numerator.isBaseUnit() && denominator.isBaseUnit()
022            ? null
023            : combine(numerator.getBaseUnit(), denominator.getBaseUnit()),
024        numerator,
025        denominator);
026  }
027
028  MomentOfInertiaUnit(
029      MomentOfInertiaUnit baseUnit,
030      UnaryFunction toBaseConverter,
031      UnaryFunction fromBaseConverter,
032      String name,
033      String symbol) {
034    super(baseUnit, toBaseConverter, fromBaseConverter, name, symbol);
035  }
036
037  /**
038   * Combines an angular momentum and angular velocity unit to form a moment of inertia unit.
039   *
040   * @param momentumUnit the unit of angular momentum
041   * @param velocityUnit the unit of angular velocity
042   * @return the combined moment of inertia unit
043   */
044  public static MomentOfInertiaUnit combine(
045      AngularMomentumUnit momentumUnit, AngularVelocityUnit velocityUnit) {
046    return cache.combine(momentumUnit, velocityUnit);
047  }
048
049  @Override
050  public MomentOfInertiaUnit getBaseUnit() {
051    return (MomentOfInertiaUnit) super.getBaseUnit();
052  }
053
054  @Override
055  public MomentOfInertia of(double magnitude) {
056    return new MomentOfInertia(magnitude, toBaseUnits(magnitude), this);
057  }
058
059  @Override
060  public MomentOfInertia ofBaseUnits(double baseUnitMagnitude) {
061    return new MomentOfInertia(fromBaseUnits(baseUnitMagnitude), baseUnitMagnitude, this);
062  }
063
064  @Override
065  public MomentOfInertia zero() {
066    return (MomentOfInertia) super.zero();
067  }
068
069  @Override
070  public MomentOfInertia one() {
071    return (MomentOfInertia) super.one();
072  }
073
074  @Override
075  public VelocityUnit<MomentOfInertiaUnit> per(TimeUnit time) {
076    return VelocityUnit.combine(this, time);
077  }
078
079  /**
080   * Creates a ratio unit between this unit and an arbitrary other unit.
081   *
082   * @param other the other unit
083   * @param <U> the type of the other unit
084   * @return the ratio unit
085   */
086  public <U extends Unit> PerUnit<MomentOfInertiaUnit, U> per(U other) {
087    return PerUnit.combine(this, other);
088  }
089
090  /**
091   * Converts a measurement value in terms of another unit to this unit.
092   *
093   * @param magnitude the magnitude of the measurement in terms of the other unit
094   * @param otherUnit the other unit
095   * @return the value of the measurement in terms of this unit
096   */
097  public double convertFrom(double magnitude, MomentOfInertiaUnit otherUnit) {
098    return fromBaseUnits(otherUnit.toBaseUnits(magnitude));
099  }
100}