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.Angle;
008import edu.wpi.first.units.measure.MutAngle;
009
010/**
011 * Unit of angular dimension.
012 *
013 * <p>This is the base type for units of angular dimension. It is also used to specify the dimension
014 * for {@link Measure}: <code>Measure&lt;AngleUnit&gt;</code>.
015 *
016 * <p>Actual units (such as {@link Units#Degrees} and {@link Units#Radians}) can be found in the
017 * {@link Units} class.
018 */
019// technically, angles are unitless dimensions
020// eg MassUnit * DistanceUnit * VelocityUnit<AngleUnit> is equivalent to (MassUnit * DistanceUnit) /
021// TimeUnit - otherwise known
022// as PowerUnit - in other words, VelocityUnit<AngleUnit> is /actually/ Frequency
023public final class AngleUnit extends Unit {
024  AngleUnit(AngleUnit baseUnit, double baseUnitEquivalent, String name, String symbol) {
025    super(baseUnit, baseUnitEquivalent, name, symbol);
026  }
027
028  AngleUnit(
029      AngleUnit baseUnit,
030      UnaryFunction toBaseConverter,
031      UnaryFunction fromBaseConverter,
032      String name,
033      String symbol) {
034    super(baseUnit, toBaseConverter, fromBaseConverter, name, symbol);
035  }
036
037  @Override
038  public AngleUnit getBaseUnit() {
039    return (AngleUnit) super.getBaseUnit();
040  }
041
042  @Override
043  public Angle of(double magnitude) {
044    return Angle.ofRelativeUnits(magnitude, this);
045  }
046
047  @Override
048  public Angle ofBaseUnits(double baseUnitMagnitude) {
049    return Angle.ofBaseUnits(baseUnitMagnitude, this);
050  }
051
052  @Override
053  public MutAngle mutable(double initialMagnitude) {
054    return new MutAngle(initialMagnitude, toBaseUnits(initialMagnitude), this);
055  }
056
057  @Override
058  public AngularVelocityUnit per(TimeUnit period) {
059    return AngularVelocityUnit.combine(this, period);
060  }
061
062  /**
063   * Creates a ratio unit between this unit and an arbitrary other unit.
064   *
065   * @param other the other unit
066   * @param <U> the type of the other unit
067   * @return the ratio unit
068   */
069  public <U extends Unit> PerUnit<AngleUnit, U> per(U other) {
070    return PerUnit.combine(this, other);
071  }
072
073  /**
074   * Converts a measurement value in terms of another angle unit to this unit.
075   *
076   * @param magnitude the magnitude of the measurement in terms of the other angle unit
077   * @param otherUnit the other angle unit
078   * @return the value of the measurement in terms of this unit
079   */
080  public double convertFrom(double magnitude, AngleUnit otherUnit) {
081    return fromBaseUnits(otherUnit.toBaseUnits(magnitude));
082  }
083
084  @Override
085  public Angle zero() {
086    return (Angle) super.zero();
087  }
088
089  @Override
090  public Angle one() {
091    return (Angle) super.one();
092  }
093}