Найти в Дзене
Репетитор IT mentor

Проблемы использования тригонометрических функций в программировании

Оглавление

Проблема 1

В большинстве языков программирования тригонометрические функции принимают аргумент, который имеет смысл угла, в виде радиан, а не градусов. Поэтому многие начинающие разработчики долго пытаются отловить ошибку в математических вычислениях. Ведь, написав sin(30) они ожидают получить 0.5, так как думают, что компилятор воспринимает это выражение как синус тридцати градусов. Но вместо ожиданий получают -0.988032. При этом компилятор не выдает никаких синтаксических ошибок. С чем это связано и почему так происходит? Дело в том, как мы уже сказали ранее, компилятор думает, что под синусом стоит 30 радиан. Что соответствует в градусах 30 ⋅ ( 180 / π ) ~ 1718.87339°, что дает нам sin(1718.87339°) ~ - 0.988031612. И значение вполне нормальное, а ошибку уловить бывает очень трудно.

Приведем пример в виде кода:

Наблюдаем явное несоответствие :(
Наблюдаем явное несоответствие :(

А теперь исправим код, так чтобы нам было легче проверять значения, подставляя углы в градусах, а с помощью коэффициентов градусы переводились в нужные для компилятора радианы:

Теперь уже всё работает как хотелось бы :)
Теперь уже всё работает как хотелось бы :)

Проблема 2

При программировании графики или какой-либо геометрии бывает нужно получать угол в полярной системе координат в зависимости от радиус вектора. Радиус вектор получается движением какой-то точки или мыши вокруг условно неподвижного центра отсчета или нуля системы координат.

-3

Представим такую ситуацию, что мы хотим вращать какой-то объект-стрелку за мышкой. Координаты мыши (x; y) мы получаем от события перемещения курсора. Далее мы хотим получить угол альфа. Возникает идея получать его через арктангенс отношения y к x. В C/C++ для этого существует функция atan2() , определенная в модуле math.h (для C) и cmath ( для C++ ).

y_coord - Значение с плавающей точкой, представленное как  у-координата.
x_coord - Значение с плавающей точкой, представленное как  x-координата.
y_coord - Значение с плавающей точкой, представленное как у-координата. x_coord - Значение с плавающей точкой, представленное как x-координата.

Функция, с двумя параметрами, вычисляет арктангенс и возвращает значение арктангенса y_coord/x_coord , выраженное в радианах.

Возвращаемое значение: Угол арктангенса y_coord /x_coord, в интервале: β [-π,+π]. И вот здесь как раз скрыт подвох (!).

При анимации движения/поворота вращение может резко начаться в другую сторону, т.к. после угла +π сразу идет угол -π, можно сказать, что это точка бифуркации, где резко меняется знак. Этот функциональный разрыв лучше всего устранить так, чтобы угол плавно менялся от 0 до 2π или от 0° до 360°.

Первоначальная идею я сначала попробовал реализовать следующими образом:

(  https://onlinegdb.com/HJFXUA-Ld  )
( https://onlinegdb.com/HJFXUA-Ld )

И тут возникла интересная ошибка... На консоль выдало 224 градуса, вместо 225. Вроде мелочь, а неприятно. Даже не ожидал такого. Программа возвращает 224, а должна 225, если представить тригонометрический круг. Увеличил точность числа pi, всё равно 224.

Логика вела меня только к одному - где-то прячется ошибка округления. Результат деления чисел double и все операции возвращают тип double, но в конце, когда нужно возвращать результат, функция делает явное преобразование типов с помощью (int) и отбрасывает дробную часть.

Поэтому, были найдены решения этой проблемы 3 способами:

Все эти решения корректно возвращают 225 градусов для x = - 1 и y = -1
Все эти решения корректно возвращают 225 градусов для x = - 1 и y = -1

Таким образом, получилась функция, которая возвращает угол в диапазоне от 0° до 360°, что является удобным для программирования вращения различных предметов.

Альтернативным решением может послужить сразу нахождение косинуса угла, который можно получить из свойств скалярного произведения векторов, один из которых содержит нашу ось Ox, а другой - радиус вектор.

Проблема 3

Неточность вычислений и лишние действия, замедляющие код. Операции обратных тригонометрических функций являются довольно дорогими по времени выполнения. Поэтому, если вы сначала считаете угол с помощью acos(), чтобы потом подставить этот угол в cos(), то вы должны задуматься над бессмысленностью этих действий.

Чаще всего нам необходим cos(α) или sin(α) в каких-либо дальнейших вычислениях. А найти их можно, воспользовавшись свойствами векторного и скалярного произведения векторов.

-7
Пример, показывающий как можно наиболее простым способом найти sin() и cos() нужного угла между двумя векторами. C++.
Пример, показывающий как можно наиболее простым способом найти sin() и cos() нужного угла между двумя векторами. C++.

А с какими проблемами, связанными с геометрией или тригонометрией, вы сталкивались при программировании своих проектов? Расскажите об этом в комментариях.

Если Вам нужна помощь или репетитор по физике, математике или информатике/программированию, Вы можете написать в мою группу Репетитор IT mentor в VK

Библиотека с книгами для физиков, математиков и программистов
Репетитор IT mentor в VK
Репетитор IT mentor в Instagram
Репетитор IT mentor в telegram

Что-то пошло не так, и нам не удалось загрузить комментарии. Попробуйте ещё раз
Рекомендуем почитать
9 Операционных систем с открытым исходным кодом, которые не связаны с Linux — откройте для себя настоящие альтернативы!
Когда слышишь словосочетание «открытый исходный код», сразу вспоминаешь Linux. Но это далеко не единственная ОС с открытым кодом. Сегодня существует множество других проектов, некоторые из которых появились задолго до Linux. Plan 9 от Bell Labs — название отсылает к культовому научно-фантастическому фильму Plan 9 From Outer Space. Эта ОС стала попыткой переосмыслить, какой может быть операционная система. Руководил проектом Роб Пайк вместе с другими членами первой команды Unix. В основе Plan 9 лежала...
Разрядность ЭВМ, с разных точек зрения. § 2 погружаемся глубже
В комментариях к первой части статьи было несколько коротких, но интересных, дискуссий. И во второй части статьи я буду учитывать эти дискуссии. Поэтому начну с чуть более подробного рассмотрения некоторых прикладных и связанных с ними вопросов. Если вы еще не успели прочитать первую часть статьи, самое время сделать это сейчас Давайте ненадолго отвлечемся от разрядности ЭВМ и бросим ретроспективный взгляд на них в целом. Это поможет нам лучше понять и связанные с разрядностью вопросы. В "доисторические времена" программирование ЭВМ было нелегкой задачей...
10 скрытых возможностей Excel, которые заменят программиста 💻➡️📊
Excel — это не просто таблицы с цифрами. Современные версии содержат мощные инструменты, которые могут автоматизировать сложные задачи без единой строчки кода. Сегодня я покажу вам функции, которые заменят целый IT-отдел и сэкономят десятки часов рутинной работы! 🔗 Больше лайфхаков для офисных гениев — в Telegram-канале "Не баг, а фича" Что заменяет: Python-скрипты для обработки данных Где найти: "Данные" → "Получить данные" Power Query — это визуальная среда для: Пример из жизни: Ежемесячно сводите...
Следующая статья
Документы, вакансии и контакты