/
docNemo
/
clothes-graph
Обзор
Документация
Войти
/
docNemo
/
clothes-graph
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
src/ClothesGraph.Model/Formulas/FormulaFunctions.cs
88 строк
3 KB
docNemo
Фундамент продукта: параметрическое построение выкроек, печать, установщик
08 авг 2026, 22:17
08 авг 2026, 22:17
cd47cce
Код
Авторство
О чём код?
using System; using System.Collections.Generic; namespace ClothesGraph.Model.Formulas; /// <summary> /// Функции и константы, доступные в формулах. /// </summary> /// <remarks> /// Тригонометрия принимает и возвращает градусы: конструктор мыслит углами /// чертежа, а не радианами, и перевод в каждой формуле был бы лишним шумом. /// </remarks> public static class FormulaFunctions { private static readonly Dictionary<string, (int MinArguments, int MaxArguments, Func<double[], double> Apply)> Functions = new(StringComparer.CurrentCultureIgnoreCase) { ["sin"] = (1, 1, a => Math.Sin(ToRadians(a[0]))), ["cos"] = (1, 1, a => Math.Cos(ToRadians(a[0]))), ["tan"] = (1, 1, a => Math.Tan(ToRadians(a[0]))), ["asin"] = (1, 1, a => ToDegrees(Math.Asin(a[0]))), ["acos"] = (1, 1, a => ToDegrees(Math.Acos(a[0]))), ["atan"] = (1, 1, a => ToDegrees(Math.Atan(a[0]))), ["atan2"] = (2, 2, a => ToDegrees(Math.Atan2(a[0], a[1]))), ["sqrt"] = (1, 1, a => Math.Sqrt(a[0])), ["abs"] = (1, 1, a => Math.Abs(a[0])), ["min"] = (2, int.MaxValue, Min), ["max"] = (2, int.MaxValue, Max), ["round"] = (1, 2, a => Math.Round(a[0], a.Length > 1 ? (int)a[1] : 0, MidpointRounding.AwayFromZero)), ["floor"] = (1, 1, a => Math.Floor(a[0])), ["ceil"] = (1, 1, a => Math.Ceiling(a[0])), ["sign"] = (1, 1, a => Math.Sign(a[0])) }; private static readonly Dictionary<string, double> Constants = new(StringComparer.CurrentCultureIgnoreCase) { ["pi"] = Math.PI, ["e"] = Math.E }; public static bool IsFunction(string name) => Functions.ContainsKey(name); public static bool TryGetConstant(string name, out double value) => Constants.TryGetValue(name, out value); public static bool TryGetArity(string name, out int minimum, out int maximum) { if (Functions.TryGetValue(name, out var function)) { minimum = function.MinArguments; maximum = function.MaxArguments; return true; } minimum = maximum = 0; return false; } public static double Apply(string name, double[] arguments) => Functions.TryGetValue(name, out var function) ? function.Apply(arguments) : throw new InvalidOperationException($"Неизвестная функция «{name}»"); private static double Min(double[] values) { var result = values[0]; foreach (var value in values) if (value < result) result = value; return result; } private static double Max(double[] values) { var result = values[0]; foreach (var value in values) if (value > result) result = value; return result; } private static double ToRadians(double degrees) => degrees * Math.PI / 180.0; private static double ToDegrees(double radians) => radians * 180.0 / Math.PI; }