Уже есть две математические темы: системы счисления и кватернионы.
Так как люди просили, чтобы я написал что-либо еще, то я думал-думал и решил выбрать такой раздел как тригонометрия.
Значит, когда я был маленьким, у меня была такая идея: вы повёрнуты на угол, скажем, 30 градусов — значит до прямого угла остаётся 60. Ну, мол, 60 в 2 раза больше, чем 30, значит и расстояние вдоль соответствующей оси будет вдвое больше: x и 2x (как на картинке). НО ЭТО ТАК НЕ РАБОТАЕТ!!! НИЖЕ НАРИСОВАНО НЕПРАВИЛЬНО!
А как же тогда работает — спросите вы. И начну я повествование с теоремы Пифагора. Возьмём прямоугольный (это тот, у которого 1 угол прямой, а остальные — острые, т.е. < 90 градусов), у него катеты (стороны рядом с прямым углом) назовём a и b, а гипотенузу (сторону напротив прямого угла) c:
А как, например, зная a и b посчитать c? Вот именно на этот вопрос и отвечает теорема Пифагора. Значит, рассмотрим такую картинку:
Тут 4 любых одинаковых прямоугольных треугольника, а внутри квадрат, образованный их гипотенузами. Чему равна площадь большого квадрата?
Ну чё тут считать — подумают многие. Площадь прямоугольника равна произведению его сторон, значит в нашем случае:
А кто-то скажет, что есть еще и другой метод посчитать ту же самую площадь. Сперва он скажет, что если мы сложим два треугольника вот так (гипотенузами друг к другу):
То площадь такой фигуры (то есть двух треугольников) равна
Ну вот теперь мы говорим, что площадь одной и той же фигуры мы посчитали двумя методами, при этом результат же должен получится тот же, фигура ж не менялась. И приравниваем два результата:
И это верно для ЛЮБОГО прямоугольного треугольника.
Рассмотрим нижнюю сторону этого прямоугольного параллелепипеда. Его одна сторона Δx (разница X-координат, т. е.
Я надеюсь не надо объяснять, что
Так, это мы победили. Идём дальше!
Возьмём опять же любой прямоугольный треугольник и любой (из двух в нём) острый угол. Синус — это соотношение противолежащего катета к гипотенузе, а косинус — прилежащего катета к гипотенузе, как на картинке:
И тут первый вопрос, который у всех возникает — а почему аргументом синуса является
1. Как нам, зная альфу, считать синус.
2. Кто нам даёт гарантию, что при одном и том же значении
На вопросы буду отвечать в обратном порядке, так как первый вопрос достаточно сложный, и ответ на него БУДЕТ, но чуть позже. При этом ответ на второй вопрос — это подобие треугольников. Если вы нарисуете два любых треугольника с одним и тем же острым углом — они будут подобны по 3 углам (один угол - 90, второй одинаковый по условию, а третий = 180 - 90 - первый, т. е. тоже одинаковый). У подобных треугольников соотношения сторон напротив тех же углов всегда одинаковы.
Грубо говоря, один треугольник будет просто увеличенной (уменьшенной) копией второго, а значит все стороны во сколько то раз увеличились (например, в
Пример, стороны: 3, 4 и 5. Соотношение 3/5 = 0.6. А второй увеличенный, к примеру, в 3 раза (стороны 9, 12 и 15), соотношение: 9/15 = тоже 0.6.
Я это уже упоминал, но если один угол — α, то второй —
Теперь можно вводить тангенс (tg, у иностранцев — tan) и котангенс (ctg, у иностранцев — cot). Тангенс — соотношение противолежащего катета к прилежащему (a / b), котангенс — прилежащего катета к противолежащему (b / a), т. е. просто наоборот. Итого опять очевидные формулы:
А чему равен синус 40 градусов? Эээ, нет!
На этот вопрос ответить точно не получается (хотя можно в комплексных числах, но это другой разговор). Можно считать значения синусов, косинусов и прочего приблизительно (с любой точностью, до любого знака после запятой, но идеально точное значение выразить используя рациональные числа и алгебраические функции [+, -, *, /, √] не выйдет).
При этом для некоторых значений углов мы знаем точные значения.
И так, 30 градусов. Если взять правильный (равносторонний) треугольник, у него все углы будут равны, а значит они по 60 градусов (сумма, напоминаю, 180 у любого треугольника). Проведём из одной его вершины линию на центр противоположной стороны. Нетрудно заметить, что образовавшиеся два треугольника равны (делаем такой вывод по 3 равным сторонам), а значит соответствующие углы тоже равны.
Значит два угла у вершины D равны, а их сумма — это развёрнутый угол, т.е. 180 градусов. Значит наши углы по 90, а два этих треугольника — прямоугольные. Углы у вершины B равны (из равенства треугольников), а значит каждый вдвое меньше 60, то есть по 30 градусов. Итого мы имеем:
Так как наша линия делила сторону на две равных части, то получается, что в прямоугольном образовавшемся треугольнике катет напротив 30 градусов равен половине гипотенузы. Значит
Так, из этого можно начинать плясать.
Вот где-то на этом этапе кажется, что синусы и косинусы — это очень практично, но есть одно но! Мы можем посчитать синус только для углов от 0 до 90 градусов (для острых). А хотелось бы определить синус для любого угла (в т.ч. отрицательного). И тогда математики думали... и сказали:
Вот единичная окружность (радиус = 1), тогда давайте нарисуем из центра линию вдоль оси OX (т.е. вправо), и повернём её против часовой стрелки на угол α, тогда X координата точки — это будет
С новым вот таким определением наш угол может быть ЛЮБЫМ (если он отрицательный, то это просто значит поворачивать в другую сторону, т.е. по часовой стрелке). Если угол 370, к примеру, это 360 (полный оборот) и еще 10, поэтому у функций есть некий период:
Иными словами, каждых 360 градусов у нас функций повторяется. И это очень удобно, на самом деле.
На этом этапе надо оговориться и сказать, что дальше мы будем оперировать радианами вместо градусов. 360 градусов (полный оборот) = 2π радиан. Вообще 1 радиан — это угол, опирающийся на дугу длиной в радиус (см. картинку). Так как у нас длина окружности — 2πr, значит таких дуг (длиной по r) у нас 2π, поэтому 2π rad = 360 degrees.
Возникает вопрос — почему? Ответ кроется в том, что тогда работает 1-й замечательный предел:
Если бы синус принимал аргументы в градусах, то предел был бы равен
Вот график синуса (его можно построить самостоятельно без граф. калькулятора, но у нас практическая статья скорее, нежели теоретическая). Называется он синусоида. А вот график косинуса (напомню, чтобы не было удивлением, что
Да, это этот же график, просто немного смещённый влево (ну или вправо, она ж [функция] периодическая). Этот график тоже называется синусоида, термина косинусоида нет!
Тут вы можете заметить, что (напомню, π радиан — это 180 градусов):
Это значит, что
Я не буду тащить котангенс, потому что он редко используется на практике. Обычно достаточно тангенса, но с ним всё по аналогии.
Зная угол, мы (допустим) получаем синус, косинус и прочее. По крайней мере, понимаем что это такое для любого угла.
А как теперь наоборот, зная синус, получить угол? Для этого есть арк-функции (арксинус, арккосинус, арктангенс, арккотангенс). Кто не понял:
Всё бы хорошо, скажете вы, но какой из углов возвращает. Например, синус равен 1/2:
У нас много (бесконечно, в общем то) углов, для которых синус равен 1/2. Какой же из них должна возвращать функция? Понятно, что лишние "обороты" мы можем скипнуть, поэтому возвращать она должна угол в рамках 1 оборота. И смотрим, а какая же часть графика нашего проходит рядом с точкой 0, для которой у нас достигаются все значения синуса (от -1 до 1). Видим, что это
Если нас интересует другое значение (которое чуть правее красной выделенной зоны), то мы легко можем посчитать его по формуле:
Для косинуса ситуация еще проще:
В этом промежутке возвращает значения функция
Вы ждали этого абзаца? Не знаю зачем, ведь библиотека математики сейчас есть в любом ЯП (почти). Ну раз начал, то надо уж всё рассказать.
И так, как считать синус? Вопрос, действительно, непростой.
Идея заключается в том, чтобы «аппроксимировать» (найти похожую) функцию многочленом. Кто не знает, что такое многочлен:
Это что-то типа такого. Метод аппроксимации (разложение в ряд Тейлора) заключается в том, чтобы найти многочлен такой, чтобы как можно больше (в идеальном случае — все, тогда мы получаем 100% точность) производных совпадали с производной нашей функции в какой-то точке. Работает это, естественно, только для непрерывных функций на всей её области определения (для всех X). Не волнуйтесь, из вполне очевидных геометрических свойств это правило выполняется. Функция еще должна быть бесконечно раз дифференцируема (т.е. мы можем брать производную, производную от производной и т.д. бесконечно), что для синуса тоже работает. Еще получившийся в итоге многочлен должен сходиться (не уходить в бесконечность), что тоже выполняется. Давайте меньше слов, больше дела:
Производная идёт по кругу:
В какой точке нам удобно считать производную? Наверное, в нуле. Так и поступим!
Хорошо, а давайте возьмём многочлен пока что 4-й степени (tx⁴+ax³+bx²+cx+d). Как брать производные от многочленов я учить не буду, прочитайте...
0-я производная, т.е. сама функция (при x = 0): tx⁴+a*x³+b*x²+c*x+d = d
1-я производная (при x = 0): 4tx³+3a*x²+2b*x+c = c
2-я производная (при x = 0): 4*3t*x²+3*2*a*x+2b = 2b
3-я производная (при x = 0): 4*3*2*t*x+3*2*a=3*2*a
4-я производная (при x = 0): 4*3*2*t
...
видно, что по аналогии n-тая производная будет: n*(n-1)*(n-2)*...*1 * [буквочка возле x^n]
И давайте теперь приравняем эти производные:
d = 0
c = 1
2b = 0
3*2*a = -1
4*3*2*t = 0
Видно, что через один у нас коэффициенты равны 0, значит их мы просто игнорируем. А остальные равны то 1, то -1 (меняется всегда местами) делить на факториал (факториал n это произведение:
Итого наш многочлен будет иметь вид:
0 + 1 * x + 0 * x² - 1/(3!) * x³ + 0 * x⁴ + 1/(5!) * x⁵ + ...
Короче, привычнее это будет выглядеть на картинке:
Напоминание! Это работает при условии цикличности производной, поэтому тут НЕ градусы, а РАДИАНЫ!
А теперь давайте попробуем проверить:
А вот код, написанный за пару минут:
Увеличив точность всего на 1 (т.е. всего 5 слагаемых), мы получаем
Никто не заставляет нас для каждой функции (кроме случаев, когда вам нужна гарантия определённой точности) выводить ряд. Вот как считать тот же тангенс (тоже точность правильная до 6 знака, точность my_sin — 5 слагаемых), сделав всего то только лишь синус.
Внимание! Стоит еще раз оговорить, что хоть формула сходится для любого числа, но конечно же считать
Тут через ряд не так просто, потому что производная цикличной не будет (хотя, безусловно, можно). При этом легко показать, что арк-функции легко выражаются в интегралах. Как известно, интеграл — это площадь. А какую площадь можно считать с помощью арккосинуса (я подумал, и он оказался более удобным нежели арксинус), скажем?
Например, площадь этого кусочка (да-да, нарисовал в Пэинте...). Для удобства я бы взял радиус = 1. Тогда площадь всей окружности —
Теперь надо программировать сиё дело)
Начать надо с поиска корня, ведь такой стандартной операции тоже нету...
Отлично, теперь будем интегрировать численно. Значит, тут всё просто: будем функцию разбивать на прямоугольники, и суммировать их площадь. Например:
Вот, вот наша простая программа:
И последний штрих — сами функции. Тут прошу обратить внимание, что просто перенаправлять арксинус на арккосинус НЕЛЬЗЯ, потому что мы теряем информацию, когда переводим синус в косинус (если, к примеру, синус меньше нуля, то какой косинус? по идее, может быть и таким, и другим. но при этом арккосинус возвращает аргумент в том интервале, где синус всегда > 0). Они вместе хорошо работают на промежутке от 0 до π/2, но случай для отрицательных нужно рассмотреть отдельно.
До шестого знака, как всегда, имеем точность более чем достаточную.
Сейчас мне кажется, что таким образом считать арк-функции — не самый эффективный метод, потому что ОЧЕНЬ много времени затрачивается на суммирование всех прямоугольников про вычислении интеграла. Поэтому, действительно, намного эффективнее БЫЛО БЫ всё-таки найти ряд (он есть в Интернете, но я его никогда не выводил, а в 2 часа ночи делать это не хочу...) и считать всего несколько слагаемых вместо таких длинных ресурсозатратных операций.
В любом случае, моя задача — показать суть. Надеюсь, у меня это получилось.
Было бы неправильно так и не решить эту задачу...
Давайте длину, на которую мы хотим переместиться, назовём
А теперь предлагаю посчитать реальное соотношение передвижения по осям.
Так как люди просили, чтобы я написал что-либо еще, то я думал-думал и решил выбрать такой раздел как тригонометрия.
Формулируем задачу
Начнём, наверное, с постановки вопроса. Вот делаете вы, скажем, AirBrake (или CamHack). Вы получили угол поворота камеры (в градусах / радианах) и хотите понять как должны измениться координаты при полёте. И вот тут-то вы сталкиваетесь с проблемами «а как»?Значит, когда я был маленьким, у меня была такая идея: вы повёрнуты на угол, скажем, 30 градусов — значит до прямого угла остаётся 60. Ну, мол, 60 в 2 раза больше, чем 30, значит и расстояние вдоль соответствующей оси будет вдвое больше: x и 2x (как на картинке). НО ЭТО ТАК НЕ РАБОТАЕТ!!! НИЖЕ НАРИСОВАНО НЕПРАВИЛЬНО!
Теорема Пифагора
А как же тогда работает — спросите вы. И начну я повествование с теоремы Пифагора. Возьмём прямоугольный (это тот, у которого 1 угол прямой, а остальные — острые, т.е. < 90 градусов), у него катеты (стороны рядом с прямым углом) назовём a и b, а гипотенузу (сторону напротив прямого угла) c:
А как, например, зная a и b посчитать c? Вот именно на этот вопрос и отвечает теорема Пифагора. Значит, рассмотрим такую картинку:
Тут 4 любых одинаковых прямоугольных треугольника, а внутри квадрат, образованный их гипотенузами. Чему равна площадь большого квадрата?
Ну чё тут считать — подумают многие. Площадь прямоугольника равна произведению его сторон, значит в нашем случае:
(a + b) * (a + b) = a² + 2ab + b²
А кто-то скажет, что есть еще и другой метод посчитать ту же самую площадь. Сперва он скажет, что если мы сложим два треугольника вот так (гипотенузами друг к другу):
То площадь такой фигуры (то есть двух треугольников) равна
a * b
(один катет равен a, другой — b). Тогда площадь 4 треугольников, очевидно, вдвое больше: 2ab
. А наша картинка (большой квадрат) состоит из 4 треугольников и внутри квадрата. Тогда площадь внутреннего квадрата: c * c = c²
, а всей картинки: 2ab + c²
.Ну вот теперь мы говорим, что площадь одной и той же фигуры мы посчитали двумя методами, при этом результат же должен получится тот же, фигура ж не менялась. И приравниваем два результата:
т-ма Пифагора:
a² + 2ab + b² = 2ab + c²
=> (сокращаем 2ab)
a² + b² = c²
Расстояние в пространстве
Классно — скажите вы, но зачем ты нам это всё рассказываешь? Давайте попробуем теперь посчитать расстояние между двумя точками в пространстве, зная их координаты.Рассмотрим нижнюю сторону этого прямоугольного параллелепипеда. Его одна сторона Δx (разница X-координат, т. е.
d - a
), другая — Δz (аналогично, f - c
). Ну тогда нижняя диагональ (нижняя сторона жёлтого выделенного треугольника) считается по теореме Пифагора, равна она √(Δx² + Δz²)
. Но жёлтый треугольник — он ведь тоже прямоугольный (почему? аксиомы стереометрии, из которых следует теорема о трех перпендикулярах. в нашем случае вертикальная ось перпендикулярна горизонтальной плоскости, и это очевидно), и у него один катет — √(Δx² + Δz²)
, а второй — Δy (e - b
). И получается, что всё суммарное расстояние мы можем тоже посчитать просто, равно оно: √(√(Δx² + Δz²)² + Δy²) = √(Δx² + Δy² + Δz²)
.Я надеюсь не надо объяснять, что
√a
— это такое число, которое в квадрате даёт a
: √25 = 5, потому что 5 * 5 = 25.
Расстояние между точками на Lua:
local d = getDistanceBetweenCoords3d(a, b, c, d, e, f)
Ровно то же самое:
local dx = d - a
local dy = e - b
local dz = f - c
local d = math.sqrt(dx * dx + dy * dy + dz * dz)
Синус и косинус
Возьмём опять же любой прямоугольный треугольник и любой (из двух в нём) острый угол. Синус — это соотношение противолежащего катета к гипотенузе, а косинус — прилежащего катета к гипотенузе, как на картинке:
И тут первый вопрос, который у всех возникает — а почему аргументом синуса является
α
, а значение синуса — a / c
. Иными словами:1. Как нам, зная альфу, считать синус.
2. Кто нам даёт гарантию, что при одном и том же значении
α
у нас будет получаться одно и то же значение a / c
(то есть синус).На вопросы буду отвечать в обратном порядке, так как первый вопрос достаточно сложный, и ответ на него БУДЕТ, но чуть позже. При этом ответ на второй вопрос — это подобие треугольников. Если вы нарисуете два любых треугольника с одним и тем же острым углом — они будут подобны по 3 углам (один угол - 90, второй одинаковый по условию, а третий = 180 - 90 - первый, т. е. тоже одинаковый). У подобных треугольников соотношения сторон напротив тех же углов всегда одинаковы.
Грубо говоря, один треугольник будет просто увеличенной (уменьшенной) копией второго, а значит все стороны во сколько то раз увеличились (например, в
k
раз). Тогда соотношение сторон в одном будет: a / b
, а другом: (k * a) / (k * b) = a / b
, так как k сокращается.Пример, стороны: 3, 4 и 5. Соотношение 3/5 = 0.6. А второй увеличенный, к примеру, в 3 раза (стороны 9, 12 и 15), соотношение: 9/15 = тоже 0.6.
Я это уже упоминал, но если один угол — α, то второй —
90 - α
(сумма углов треугольника 180 градусов). Значит, очевидно:
Формулы:
sin(a) = cos(90 - a)
cos(a) = sin(90 - a)
Тангенс и котангенс
Теперь можно вводить тангенс (tg, у иностранцев — tan) и котангенс (ctg, у иностранцев — cot). Тангенс — соотношение противолежащего катета к прилежащему (a / b), котангенс — прилежащего катета к противолежащему (b / a), т. е. просто наоборот. Итого опять очевидные формулы:
Формулы:
tg(a) = a / b = (a / c) / (b / c) = sin(a) / cos(a)
ctg(a) = b / a = cos(a) / sin(a)
tg(a) = ctg(90 - a)
ctg(a) = tg(90 - a)
tg(a) = 1 / ctg(a)
Значения функций в некоторых точках
А чему равен синус 40 градусов? Эээ, нет!
На этот вопрос ответить точно не получается (хотя можно в комплексных числах, но это другой разговор). Можно считать значения синусов, косинусов и прочего приблизительно (с любой точностью, до любого знака после запятой, но идеально точное значение выразить используя рациональные числа и алгебраические функции [+, -, *, /, √] не выйдет).
При этом для некоторых значений углов мы знаем точные значения.
И так, 30 градусов. Если взять правильный (равносторонний) треугольник, у него все углы будут равны, а значит они по 60 градусов (сумма, напоминаю, 180 у любого треугольника). Проведём из одной его вершины линию на центр противоположной стороны. Нетрудно заметить, что образовавшиеся два треугольника равны (делаем такой вывод по 3 равным сторонам), а значит соответствующие углы тоже равны.
Значит два угла у вершины D равны, а их сумма — это развёрнутый угол, т.е. 180 градусов. Значит наши углы по 90, а два этих треугольника — прямоугольные. Углы у вершины B равны (из равенства треугольников), а значит каждый вдвое меньше 60, то есть по 30 градусов. Итого мы имеем:
Так как наша линия делила сторону на две равных части, то получается, что в прямоугольном образовавшемся треугольнике катет напротив 30 градусов равен половине гипотенузы. Значит
sin(30) = 1/2
. А теперь вспоминаем ту самую теорему Пифагора.
Её следствие:
a² + b² = c²
=> (делим всё уравнение на c²)
a²/c² + b²/c² = 1
(a/c)² + (b/c)² = 1
=> (a, b и c у нас любые, поэтому рассмотрим угол φ напротив стороны a)
sin(φ)² + cos(φ)² = 1
Формулы:
sin(30) = 1/2
sin(30)² + cos(30)² = 1
=> 1/4 + cos(30)² = 1
=> cos(30)² = 3/4
=> cos(30) = √(3)/2
Формулы (2):
sin(60) = cos(30) = √(3)/2
cos(60) = sin(30) = 1/2
tg(30) = ctg(60) = sin(30)/cos(30) = (1/2)/(√(3)/2) = 1/√3
tg(60) = ctg(30) = 1/tg(30) = √3
Переопределение тригонометрических функций
Вот где-то на этом этапе кажется, что синусы и косинусы — это очень практично, но есть одно но! Мы можем посчитать синус только для углов от 0 до 90 градусов (для острых). А хотелось бы определить синус для любого угла (в т.ч. отрицательного). И тогда математики думали... и сказали:
Вот единичная окружность (радиус = 1), тогда давайте нарисуем из центра линию вдоль оси OX (т.е. вправо), и повернём её против часовой стрелки на угол α, тогда X координата точки — это будет
cos(α)
, а Y координата — sin(α)
. Если мы рассмотрим случай (0 < α < 90), то наше «новое» определение НЕ противоречит старому. В выделенном треугольнике гипотенуза (т.е. радиус) равна 1, так что старое определение работает. Но!С новым вот таким определением наш угол может быть ЛЮБЫМ (если он отрицательный, то это просто значит поворачивать в другую сторону, т.е. по часовой стрелке). Если угол 370, к примеру, это 360 (полный оборот) и еще 10, поэтому у функций есть некий период:
Период = 2π (360 градусов):
sin(360 + a) = sin(a)
cos(360 + a) = cos(a)
На этом этапе надо оговориться и сказать, что дальше мы будем оперировать радианами вместо градусов. 360 градусов (полный оборот) = 2π радиан. Вообще 1 радиан — это угол, опирающийся на дугу длиной в радиус (см. картинку). Так как у нас длина окружности — 2πr, значит таких дуг (длиной по r) у нас 2π, поэтому 2π rad = 360 degrees.
Возникает вопрос — почему? Ответ кроется в том, что тогда работает 1-й замечательный предел:
Если бы синус принимал аргументы в градусах, то предел был бы равен
π/180
, что не равно 1. Поэтому производная синуса не будет цикличной, мы бы не могли так просто разложить синус в ряд (а если бы и могли, то у нас все равно бы там фигурировало число π) и так далее и тому подобное.Графики функций синуса
Вот график синуса (его можно построить самостоятельно без граф. калькулятора, но у нас практическая статья скорее, нежели теоретическая). Называется он синусоида. А вот график косинуса (напомню, чтобы не было удивлением, что
cos(x)=sin(90-x)
, и да, все наши формулы прекрасно работают для любого x, НЕ только от 0 до 90)Да, это этот же график, просто немного смещённый влево (ну или вправо, она ж [функция] периодическая). Этот график тоже называется синусоида, термина косинусоида нет!
Тут вы можете заметить, что (напомню, π радиан — это 180 градусов):
Заметим:
sin(π + x) = -sin(x)
cos(π + x) = -cos(x)
sin(x) / cos(x) = sin(π + x) / cos(π + x)
. А значит, что период тангенса (и котангенса) — вдвое меньше, всего один π. И вот график:Я не буду тащить котангенс, потому что он редко используется на практике. Обычно достаточно тангенса, но с ним всё по аналогии.
Обратные (арк-) функции
Зная угол, мы (допустим) получаем синус, косинус и прочее. По крайней мере, понимаем что это такое для любого угла.
А как теперь наоборот, зная синус, получить угол? Для этого есть арк-функции (арксинус, арккосинус, арктангенс, арккотангенс). Кто не понял:
Демонстрация:
sin(1) = 0.841470985
=> arcsin(0.841470985) = 1
(тут угол 1 в радианах, напомню)
У нас много (бесконечно, в общем то) углов, для которых синус равен 1/2. Какой же из них должна возвращать функция? Понятно, что лишние "обороты" мы можем скипнуть, поэтому возвращать она должна угол в рамках 1 оборота. И смотрим, а какая же часть графика нашего проходит рядом с точкой 0, для которой у нас достигаются все значения синуса (от -1 до 1). Видим, что это
от -π/2 до π/2
.Если нас интересует другое значение (которое чуть правее красной выделенной зоны), то мы легко можем посчитать его по формуле:
sin(π - x) = sin(x)
, эта формула очевидна из графика. Ну и прибавлять (либо отнимать) сколько хотим раз 2π (полный оборот) и к одному, и ко второму значению. Итого:
Код:
sin(x) = 0.841470985
Тогда, например: arcsin(0.841470985) = 1
Все ВОЗМОЖНЫЕ значения x (угла):
x = 1
x = 1 + 2π
x = 1 - 2π
x = 1 + 4π
x = 1 - 4π
x = 1 + 6π
x = 1 - 6π
...
x = π - 1
x = π - 1 + 2π
x = π - 1 - 2π
x = π - 1 + 4π
x = π - 1 - 4π
x = π - 1 + 6π
x = π - 1 - 6π
...
Для косинуса ситуация еще проще:
В этом промежутке возвращает значения функция
arccos(x)
. Дальше по аналогии с синусом мы можем найти все возможные значения X.Разложение функций в ряд (приближённое вычисление)
Вы ждали этого абзаца? Не знаю зачем, ведь библиотека математики сейчас есть в любом ЯП (почти). Ну раз начал, то надо уж всё рассказать.
И так, как считать синус? Вопрос, действительно, непростой.
Идея заключается в том, чтобы «аппроксимировать» (найти похожую) функцию многочленом. Кто не знает, что такое многочлен:
Это что-то типа такого. Метод аппроксимации (разложение в ряд Тейлора) заключается в том, чтобы найти многочлен такой, чтобы как можно больше (в идеальном случае — все, тогда мы получаем 100% точность) производных совпадали с производной нашей функции в какой-то точке. Работает это, естественно, только для непрерывных функций на всей её области определения (для всех X). Не волнуйтесь, из вполне очевидных геометрических свойств это правило выполняется. Функция еще должна быть бесконечно раз дифференцируема (т.е. мы можем брать производную, производную от производной и т.д. бесконечно), что для синуса тоже работает. Еще получившийся в итоге многочлен должен сходиться (не уходить в бесконечность), что тоже выполняется. Давайте меньше слов, больше дела:
Производная идёт по кругу:
sin(x) —> cos(x) —> -sin(x) —> -cos(x) —> sin(x) —> ...
В какой точке нам удобно считать производную? Наверное, в нуле. Так и поступим!
Чему равна:
sin(0) = 0
cos(0) = 1
-sin(0) = 0
-cos(0) = -1
0-я производная, т.е. сама функция (при x = 0): tx⁴+a*x³+b*x²+c*x+d = d
1-я производная (при x = 0): 4tx³+3a*x²+2b*x+c = c
2-я производная (при x = 0): 4*3t*x²+3*2*a*x+2b = 2b
3-я производная (при x = 0): 4*3*2*t*x+3*2*a=3*2*a
4-я производная (при x = 0): 4*3*2*t
...
видно, что по аналогии n-тая производная будет: n*(n-1)*(n-2)*...*1 * [буквочка возле x^n]
И давайте теперь приравняем эти производные:
d = 0
c = 1
2b = 0
3*2*a = -1
4*3*2*t = 0
Видно, что через один у нас коэффициенты равны 0, значит их мы просто игнорируем. А остальные равны то 1, то -1 (меняется всегда местами) делить на факториал (факториал n это произведение:
1*2*3*...*n
).Итого наш многочлен будет иметь вид:
0 + 1 * x + 0 * x² - 1/(3!) * x³ + 0 * x⁴ + 1/(5!) * x⁵ + ...
Короче, привычнее это будет выглядеть на картинке:
Напоминание! Это работает при условии цикличности производной, поэтому тут НЕ градусы, а РАДИАНЫ!
А теперь давайте попробуем проверить:
А вот код, написанный за пару минут:
Увеличив точность всего на 1 (т.е. всего 5 слагаемых), мы получаем
0.841471
, т.е. точность до ШЕСТОГО ЗНАКА после запятой.Никто не заставляет нас для каждой функции (кроме случаев, когда вам нужна гарантия определённой точности) выводить ряд. Вот как считать тот же тангенс (тоже точность правильная до 6 знака, точность my_sin — 5 слагаемых), сделав всего то только лишь синус.
Внимание! Стоит еще раз оговорить, что хоть формула сходится для любого числа, но конечно же считать
sin(100 rad)
такой формулой нерационально (точность будет СИЛЬНО деградировать). Намного эффективнее будет отнимать от 100 радиан по 2π до тех пор, пока число не будет близким к нулю (от 0 до 2π, а желательно вообще от 0 до π, применяя формулу sin(π + x) = -sin(x)
).Вычисление арк-функций (обратных)
Тут через ряд не так просто, потому что производная цикличной не будет (хотя, безусловно, можно). При этом легко показать, что арк-функции легко выражаются в интегралах. Как известно, интеграл — это площадь. А какую площадь можно считать с помощью арккосинуса (я подумал, и он оказался более удобным нежели арксинус), скажем?
Например, площадь этого кусочка (да-да, нарисовал в Пэинте...). Для удобства я бы взял радиус = 1. Тогда площадь всей окружности —
πr² = π
, а нашей пиццы — πr² * φ / (2π) = φr² / 2 = φ / 2
, где φ — угол дуги (который в центре окружности). Вычитаем отсюда площадь треугольника: 1/2 * x * √(1 - x²)
. Потом выражаем площадь через интеграл, и дальше приравниваем. Из уравнения выводим чему равен арккосинус:Теперь надо программировать сиё дело)
Начать надо с поиска корня, ведь такой стандартной операции тоже нету...
Отлично, теперь будем интегрировать численно. Значит, тут всё просто: будем функцию разбивать на прямоугольники, и суммировать их площадь. Например:
Вот, вот наша простая программа:
И последний штрих — сами функции. Тут прошу обратить внимание, что просто перенаправлять арксинус на арккосинус НЕЛЬЗЯ, потому что мы теряем информацию, когда переводим синус в косинус (если, к примеру, синус меньше нуля, то какой косинус? по идее, может быть и таким, и другим. но при этом арккосинус возвращает аргумент в том интервале, где синус всегда > 0). Они вместе хорошо работают на промежутке от 0 до π/2, но случай для отрицательных нужно рассмотреть отдельно.
До шестого знака, как всегда, имеем точность более чем достаточную.
Сейчас мне кажется, что таким образом считать арк-функции — не самый эффективный метод, потому что ОЧЕНЬ много времени затрачивается на суммирование всех прямоугольников про вычислении интеграла. Поэтому, действительно, намного эффективнее БЫЛО БЫ всё-таки найти ряд (он есть в Интернете, но я его никогда не выводил, а в 2 часа ночи делать это не хочу...) и считать всего несколько слагаемых вместо таких длинных ресурсозатратных операций.
В любом случае, моя задача — показать суть. Надеюсь, у меня это получилось.
Решаем задачу, сформулированную в первом абзаце
Было бы неправильно так и не решить эту задачу...
Давайте длину, на которую мы хотим переместиться, назовём
d
. Тогда синус 30 (он же 1/2) — это x/d
, отсюда x = d * sin(30)
. Аналогично с "2x" (будем использовать обозначения с рисунка, это НЕ ДВА ИКСА, просто чтобы не перерисовывать). 2x = d * sin(60)
.А теперь предлагаю посчитать реальное соотношение передвижения по осям.
Считаем:
2x / x = (d * sin(60)) / (d * sin(30)) = sin(60) / sin(30) = 1.73205081
И НИКАК НЕ 2!!!
Последнее редактирование: