angleClosestTo method

Angle angleClosestTo(
  1. Angle angle, [
  2. bool strict = false
])

Find the angle within this range closest to the specified angle.

If strict is true, then only the actual range is used regardless of whether it falls within the nominal 0-360 degree range. If strict is false then the closest angle as if the ranges were projected onto a single circle is returned.

Implementation

Angle angleClosestTo(Angle angle, [bool strict = false]) {
  // Contains?
  if (!strict && contains360(angle)) {
    return angle;
  } else if (contains(angle)) {
    return angle;
  }

  // Not contained... return closest endpoint.
  if (!strict) {
    final angRev0 = angle.angle360;
    late Angle closest;
    num minDeltaRad = angle360.mks.toDouble();
    final ranges = ranges360;
    num deltaStartRad;
    num deltaStartRadRev;
    num deltaEndRad;
    num deltaEndRadRev;
    for (final range in ranges) {
      deltaStartRad = (range.startAngle.mks.toDouble() - angRev0.mks.toDouble()).abs();
      deltaStartRadRev = tau + range.startAngle.mks.toDouble() - angRev0.mks.toDouble();
      deltaStartRad = min(deltaStartRad, deltaStartRadRev);
      deltaEndRad = (range.endAngle.mks.toDouble() - angRev0.mks.toDouble()).abs();
      deltaEndRadRev = tau + range.endAngle.mks.toDouble() - angRev0.mks.toDouble();
      deltaEndRad = min(deltaEndRad, deltaEndRadRev);
      if (deltaStartRad < minDeltaRad) {
        closest = range.startAngle;
        minDeltaRad = deltaStartRad;
      }
      if (deltaEndRad < minDeltaRad) {
        closest = range.endAngle;
        minDeltaRad = deltaEndRad;
      }
    }
    return closest;
  } else {
    final num deltaStartRad = (startAngle.mks.toDouble() - angle.mks.toDouble()).abs();
    final num deltaEndRad = (endAngle.mks.toDouble() - angle.mks.toDouble()).abs();
    return (deltaStartRad <= deltaEndRad) ? Angle(rad: deltaStartRad) : Angle(rad: deltaEndRad);
  }
}