Всем привет! Как и понятное по заголовку, это продолжение предыдущей статьи с той же темой, но теперь мы будем рассматривать аппроксимационные кривые. В прошлой статье я рассматривал семейство интерполяционных кривых вида: Функции параметра  для интерполяции принимают значения от  до  и возвращают значения от  до . Как я и обещал в предыдущей статье, противоположные функции будут в этой статье и текущая тема будет уже не интерполяция, а аппроксимация. В случае аппроксимации нам нужно будет учитывать все точки в любом месте, тогда как в случае интерполяции в узлах значения функции определяются значениями узловых точек. Это значит, что параметр влияния всегда будет больше  для всех, кроме крайних, точек — у крайних он может быть равен  на противоположном конце кривой. В противном случае в крайних точках параметр влияния на другом конце кривой будет меньше  — для всех точек кривая влияния одинаковая, но с разным сдвигом. А теперь, барабанная дробь, это семейство не только аппроксимирует, но и позволяет регулировать точность аппроксимации! Это легко доказывается. При  справедливо неравенство, то есть график первой функции сильнее прижат к оси . Если провести аналогию с расстоянием ( принимаем за расстояние до точки), то на первом графике расстояние влияет сильнее, но одинаковое в  и . Но важно помнить, что при очень высокой степени точность на самих точках будет высокая, но поблизости значение функции будет прижато к значению  точки. Настало время перейти непосредственно к рассмотрению функций параметра. Функции могут быть почти те же, что и для интерполяции, только будет отличаться их применение — нужно будет вычитать их значение из максимального. Примерами таких функций являются, аналогично с интерполяцией, , , ,  и другие. Не отступая от плана предыдущей статьи, первая функция на очереди — степенная. Если для интерполяции мы делили, то здесь нам придется умножать. Сам вид тоже чуточку меняется и, соответственно, выглядит так. где  — параметр точности аппроксимации. В скобках у нас возведение в квадрат — это и есть применение степенной функции, но я рекомендую использовать степень выше или равную , иначе функция выглядит ломаной. Перейдем ко всеми любимой тригонометрии. Первыми рассмотрим синус и косинус, как и в предыдущей статье. Поскольку синус и косинус — одинаковые функции, но с разным сдвигом, рассматривать я буду косинус. Но можно без проблем заменить косинус на синус в конечной формуле.  Итак, наша функция должна возвращать    при входном , и наоборот, соответственно. Параметров всего два — растяжение и сдвиг. Максимальный полупериод может быть равен , поэтому формула растяжения будет такой: , где  — коэффициент . С добавлением сдвига она превращается в .  Теперь нам надо привести формулу к нужному виду, поэтому окончательный вид немного другой: Коэффициенты ограничены — , а . Остается написать код для синусоидой аппроксимации. Настало время рассмотреть функции вида . В рамках данной статьи, хочу заметить, что они не очень удобные, поскольку при некоторых значениях параметра контролировать степень аппроксимации почти невозможно. Но для программирования это может оказаться полезным, поскольку возводить в очень большие степени не потребуется. Для функции такого вида есть несколько вариантов, подходящих для аппроксимации, но я выберу лучшие два. Сверху у нас должна быть степень наибольшая при  и наименьшая при . Для этого можно использовать квадратичную функцию, с которой мы уже познакомились в этой статье. По свойству степеней у нас степени перемножаются: Если раскрыть, получается три коэффициента: Второй коэффициент не стоит делать слишком большим, иначе будет трудно контролировать аппроксимацию. В плане кода это будет два возведения в степень, но не очень большие. Ну и последний шаг для этого блока — код. Продолжаем тригонометрию. Из основных тригонометрических функций осталась одна — тангенс. Для тангенса все аналогично с синусом, вид такой: Ограничения коэффициентов — , , . Для нужной функции в коде меняем только косинус на тангенс в коде из блока про синус. Да уж, халявный блок получается, по готовенькому прошли). Ну и куда же без кастомной функции и самой маленькой оптимизации кода: В данной статье рассмотрены лишь немногие функции, остальные остаются можете рассмотреть самостоятельно. Код в главной части статьи приведен полностью по материалу, то есть нет оптимизаций, из-за которых код будет по виду отличаться от самой формулы. Используется класс для точек от движка Unity, вещественные числа типа float именно из-за движка и применяются, для чистого C# нужно использовать double. Хочу еще немножко сказать про аппроксимацию. При работе с большим количеством данных, важно помнить, что количество итераций растет линейно. Данное семейство также позволяет экспериментировать с различными функциями — забавно посмотреть на аппроксимацию с функциями вида . Возможностей для применения такой аппроксимации много, но три я хочу выделить. Первая, и самая очевидная, — это аппроксимация движения между точками. Функционал позволяет настроить это так, как вам нужно. Вторая — это аппроксимация данных, предсказание новых по старым. На мой взгляд, это самая перспективная область для аппроксимации. Ну и третья — обработка изображений, функция сглаживания. При мощном компе можно обрабатывать большие изображения, либо ограничиваться ближайшими точками. Можно увеличивать изображение, но тогда нельзя забывать оставлять узловые значения, чтобы оно не теряло четкость без надобности. Надеюсь, вам где-нибудь это пригодится)