001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.numbers.angle;
018
019/**
020 * Utility class where all {@code double} values are assumed to be in
021 * radians.
022 *
023 * @see PlaneAngle
024 */
025public final class PlaneAngleRadians {
026    /** Value of \( \pi \): {@value}. */
027    public static final double PI = Math.PI;
028    /** Value of \( 2\pi \): {@value}. */
029    public static final double TWO_PI = 2 * PI;
030    /** Value of \( \pi/2 \): {@value}. */
031    public static final double PI_OVER_TWO = 0.5 * PI;
032    /** Value of \( 3\pi/2 \): {@value}. */
033    public static final double THREE_PI_OVER_TWO = 3 * PI_OVER_TWO;
034
035    /** Utility class. */
036    private PlaneAngleRadians() {}
037
038    /**
039     * Normalize an angle in an interval of size 2π around a
040     * center value.
041     *
042     * @param angle Value to be normalized.
043     * @param center Center of the desired interval for the result.
044     * @return {@code a - 2 * k} with integer {@code k} such that
045     * {@code center - pi <= a - 2 * k * pi < center + pi}.
046     */
047    public static double normalize(double angle,
048                                   double center) {
049        final PlaneAngle a = PlaneAngle.ofRadians(angle);
050        final PlaneAngle c = PlaneAngle.ofRadians(center);
051        return a.normalize(c).toRadians();
052    }
053
054    /**
055     * Normalize an angle to be in the range [-&pi;, &pi;).
056     *
057     * @param angle Value to be normalized.
058     * @return {@code a - 2 * k} with integer {@code k} such that
059     * {@code -pi <= a - 2 * k * pi < pi}.
060     */
061    public static double normalizeBetweenMinusPiAndPi(double angle) {
062        return PlaneAngle.ofRadians(angle).normalize(PlaneAngle.ZERO).toRadians();
063    }
064
065    /**
066     * Normalize an angle to be in the range [0, 2&pi;).
067     *
068     * @param angle Value to be normalized.
069     * @return {@code a - 2 * k} with integer {@code k} such that
070     * {@code 0 <= a - 2 * k * pi < 2 * pi}.
071     */
072    public static double normalizeBetweenZeroAndTwoPi(double angle) {
073        return PlaneAngle.ofRadians(angle).normalize(PlaneAngle.PI).toRadians();
074    }
075}