/* * 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 SPAngle { public const float PI = 3.1415926536f; public const float TWO_PI = 6.2831853072f; public const float HALF_OF_PI = 1.5707963268f; public const float THIRD_OF_PI = 1.0471975512f; public const float FOURTH_OF_PI = 0.7853981634f; public const float SIXTH_OF_PI = 0.5235987756f; public const float DEGREES_IN_RADIAN = 57.295779513f; public const float TURNS_IN_RADIAN = 0.1591549431f; public const float RADIANS_IN_DEGREE = 1.745329252E-2f; public const float TURNS_IN_DEGREE = 2.7777777778E-3f; public static float RadiansToDegrees(float radians) { return radians * DEGREES_IN_RADIAN; } public static float RadiansToTurns(float radians) { return radians * TURNS_IN_RADIAN; } public static float DegreesToRadians(float degrees) { return degrees * RADIANS_IN_DEGREE; } public static float DegreesToTurns(float degrees) { return degrees * TURNS_IN_DEGREE; } public static float TurnsToRadians(float turns) { return turns * TWO_PI; } public static float TurnsToDegrees(float turns) { return turns * 360.0f; } public static float ConvertFromRadians(float 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 float ConvertFromDegrees(float 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 float ConvertFromTurns(float turns, AngleUnit toUnit) { if (toUnit == AngleUnit.RADIANS) { return turns * TWO_PI; } if (toUnit == AngleUnit.DEGREES) { return turns * 360.0f; } return turns; } public static float ConvertToRadians(float angle, AngleUnit unit) { if (unit == AngleUnit.DEGREES) { return angle * RADIANS_IN_DEGREE; } if (unit == AngleUnit.TURNS) { return angle * TWO_PI; } return angle; } public static float ConvertToDegrees(float angle, AngleUnit unit) { if (unit == AngleUnit.RADIANS) { return angle * DEGREES_IN_RADIAN; } if (unit == AngleUnit.TURNS) { return angle * 360.0f; } return angle; } public static float ConvertToTurns(float 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 float GetFullCircle(AngleUnit unit) { if (unit == AngleUnit.RADIANS) { return TWO_PI; } if (unit == AngleUnit.DEGREES) { return 360.0f; } return 1.0f; } public static float GetHalfCircle(AngleUnit unit) { if (unit == AngleUnit.RADIANS) { return PI; } if (unit == AngleUnit.DEGREES) { return 180.0f; } return 0.5f; } public static float GetQuarterCircle(AngleUnit unit) { if (unit == AngleUnit.RADIANS) { return HALF_OF_PI; } if (unit == AngleUnit.DEGREES) { return 90.0f; } return 0.25f; } public static float NormalizeRadians(float 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; } } float turns = radians * TURNS_IN_RADIAN; turns -= MathF.Floor(turns); if (range == AngleRange.SIGNED_RANGE && turns > 0.5f) { turns -= 1.0f; } return turns * TWO_PI; } public static float NormalizeDegrees(float radians, AngleRange range) { if (range == AngleRange.UNSIGNED_RANGE) { if (0.0f <= radians && radians < 360.0f) { return radians; } } else { if (-180.0f < radians && radians <= 180.0f) { return radians; } } float turns = radians * TURNS_IN_DEGREE; turns -= MathF.Floor(turns); if (range == AngleRange.SIGNED_RANGE && turns > 0.5f) { turns -= 1.0f; } return turns * 360.0f; } public static float NormalizeTurns(float turns, AngleRange range) { if (range == AngleRange.UNSIGNED_RANGE) { if (0.0f <= turns && turns < 1.0f) { return turns; } } else { if (-0.5f < turns && turns <= 0.5f) { return turns; } } float rest = turns - MathF.Floor(turns); if (range == AngleRange.SIGNED_RANGE && rest > 0.5f) { rest -= 1.0f; } return rest; } public static float Normalize(float 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); } } }