/* * Copyright 2019-2025 Andrey Pokidov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; /* * Author: Andrey Pokidov * Date: 1 Feb 2019 */ namespace Geometry { public static class DPAngle { public const double PI = 3.14159265358979324; public const double TWO_PI = 6.28318530717958648; public const double HALF_OF_PI = 1.57079632679489662; public const double THIRD_OF_PI = 1.04719755119659775; public const double FOURTH_OF_PI = 0.78539816339744831; public const double SIXTH_OF_PI = 0.523598775598298873; public const double DEGREES_IN_RADIAN = 57.2957795130823209; public const double TURNS_IN_RADIAN = 0.159154943091895336; public const double RADIANS_IN_DEGREE = 1.74532925199432958E-2; public const double TURNS_IN_DEGREE = 2.77777777777777778E-3; public static double RadiansToDegrees(double radians) { return radians * DEGREES_IN_RADIAN; } public static double RadiansToTurns(double radians) { return radians * TURNS_IN_RADIAN; } public static double DegreesToRadians(double degrees) { return degrees * RADIANS_IN_DEGREE; } public static double DegreesToTurns(double degrees) { return degrees * TURNS_IN_DEGREE; } public static double TurnsToRadians(double turns) { return turns * TWO_PI; } public static double TurnsToDegrees(double turns) { return turns * 360.0; } public static double ConvertFromRadians(double radians, AngleUnit toUnit) { if (toUnit == AngleUnit.DEGREES) { return radians * DEGREES_IN_RADIAN; } if (toUnit == AngleUnit.TURNS) { return radians * TURNS_IN_RADIAN; } return radians; } public static double ConvertFromDegrees(double degrees, AngleUnit toUnit) { if (toUnit == AngleUnit.RADIANS) { return degrees * RADIANS_IN_DEGREE; } if (toUnit == AngleUnit.TURNS) { return degrees * TURNS_IN_DEGREE; } return degrees; } public static double ConvertFromTurns(double turns, AngleUnit toUnit) { if (toUnit == AngleUnit.RADIANS) { return turns * TWO_PI; } if (toUnit == AngleUnit.DEGREES) { return turns * 360.0; } return turns; } public static double ConvertToRadians(double angle, AngleUnit unit) { if (unit == AngleUnit.DEGREES) { return angle * RADIANS_IN_DEGREE; } if (unit == AngleUnit.TURNS) { return angle * TWO_PI; } return angle; } public static double ConvertToDegrees(double angle, AngleUnit unit) { if (unit == AngleUnit.RADIANS) { return angle * DEGREES_IN_RADIAN; } if (unit == AngleUnit.TURNS) { return angle * 360.0; } return angle; } public static double ConvertToTurns(double angle, AngleUnit unit) { if (unit == AngleUnit.RADIANS) { return angle * TURNS_IN_RADIAN; } if (unit == AngleUnit.DEGREES) { return angle * TURNS_IN_DEGREE; } return angle; } public static double GetFullCircle(AngleUnit unit) { if (unit == AngleUnit.RADIANS) { return TWO_PI; } if (unit == AngleUnit.DEGREES) { return 360.0; } return 1.0; } public static double GetHalfCircle(AngleUnit unit) { if (unit == AngleUnit.RADIANS) { return PI; } if (unit == AngleUnit.DEGREES) { return 180.0; } return 0.5; } public static double GetQuarterCircle(AngleUnit unit) { if (unit == AngleUnit.RADIANS) { return HALF_OF_PI; } if (unit == AngleUnit.DEGREES) { return 90.0; } return 0.25; } public static double NormalizeRadians(double radians, AngleRange range) { if (range == AngleRange.UNSIGNED_RANGE) { if (0.0 <= radians && radians < TWO_PI) { return radians; } } else { if (-PI < radians && radians <= PI) { return radians; } } double turns = radians * TURNS_IN_RADIAN; turns -= Math.Floor(turns); if (range == AngleRange.SIGNED_RANGE && turns > 0.5) { turns -= 1.0; } return turns * TWO_PI; } public static double NormalizeDegrees(double degrees, AngleRange range) { if (range == AngleRange.UNSIGNED_RANGE) { if (0.0 <= degrees && degrees < 360.0) { return degrees; } } else { if (-180.0 < degrees && degrees <= 180.0) { return degrees; } } double turns = degrees * TURNS_IN_DEGREE; turns -= Math.Floor(turns); if (range == AngleRange.SIGNED_RANGE && turns > 0.5) { turns -= 1.0; } return turns * 360.0; } public static double NormalizeTurns(double turns, AngleRange range) { if (range == AngleRange.UNSIGNED_RANGE) { if (0.0 <= turns && turns < 1.0) { return turns; } } else { if (-0.5 < turns && turns <= 0.5) { return turns; } } double rest = turns - Math.Floor(turns); if (range == AngleRange.SIGNED_RANGE && rest > 0.5) { rest -= 1.0; } return rest; } public static double Normalize(double angle, AngleUnit unit, AngleRange range) { if (unit == AngleUnit.RADIANS) { return NormalizeRadians(angle, range); } if (unit == AngleUnit.DEGREES) { return NormalizeDegrees(angle, range); } return NormalizeTurns(angle, range); } } }