С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/6: Рейтинг темы: голосов - 6, средняя оценка - 4.50
9 / 9 / 8
Регистрация: 02.01.2017
Сообщений: 262

Неточность функции поиска угла

13.03.2017, 06:18. Показов 1355. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
написал функцию нахождения угла по 3-м точкам
C++
1
2
3
4
5
6
7
8
9
10
11
12
int LengthBetweenPoints(point a,point b)
{
     return (int)sqrt(((double)b.y-(double)a.y)*((double)b.y-(double)a.y)+((double)b.x-(double)a.x)*((double)b.x-(double)a.x));
}
 double AngleTreePoints(point a,point b,point c)
{
    double la,lb,lc;
    la=(double)LengthBetweenPoints(a,b);
    lb=(double)LengthBetweenPoints(b,c);
    lc=(double)LengthBetweenPoints(c,a);
    return acos((la*la+lb*lb-lc*lc)/(2*lb*la))*180/3.14159265;
}
Везде где только можно натыкал double, но результат все равно оставляет жклать лучшего,не подскажете что ещё можно сделать чтоб функция при a.x=0;a.y=100;b.x=0;b.y=0;c.x=200;c.y=0; выдавала 90 градусов
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
13.03.2017, 06:18
Ответы с готовыми решениями:

Ошибка в программе поиска угла преломления по данному
Помогите пожалуйста мне устранить ошибку в коде: uses crt,GraphABC; var a:longint; ug,y,z:real; x:longint; begin ...

Ошибка в программе поиска угла преломления по данному углу
Помогите пожалуйста мне устранить ошибку в коде: uses crt,GraphABC; var a:longint; ug,y,z:real; x:longint; begin ...

Реализация функции поиска нужной услуги по заданным критериям поиска.
Получил задание на тему ArrayList, не получается сделать целиком...Вот задание помогите кто чем сможет.Спасибо. Необходимо разработать...

16
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
13.03.2017, 09:12
Ну а функция почему тогда int возвращает?
1
Модератор
Эксперт С++
 Аватар для zss
13771 / 10964 / 6491
Регистрация: 18.12.2011
Сообщений: 29,241
13.03.2017, 09:16
Присоединяюсь к nmcf
и
Цитата Сообщение от imjonhson Посмотреть сообщение
(la*la+lb*lb-lc*lc)
Для прямого угла здесь должно получиться ноль.
Проверьте это в отладчике.
1
1272 / 1029 / 470
Регистрация: 25.12.2016
Сообщений: 3,333
13.03.2017, 09:30
Цитата Сообщение от imjonhson Посмотреть сообщение
AngleTreePoints
Только не Tree (дерево), а Three (три). Ещё можно добавить by: AngleByThreePoints.
0
9 / 9 / 8
Регистрация: 02.01.2017
Сообщений: 262
14.03.2017, 01:49  [ТС]
Цитата Сообщение от likehood Посмотреть сообщение
Только не Tree (дерево), а Three (три). Ещё можно добавить by: AngleByThreePoints.
иногда жалею, что языки программирования не на русском, иногда радуюсь что не на китайском.

Добавлено через 2 минуты
Цитата Сообщение от zss Посмотреть сообщение
Для прямого угла здесь должно получиться ноль.
Проверьте это в отладчике.
после смены на double помогло с углом, но значение явно не 0
(la*la+lb*lb-lc*lc) "-1.40517e-10"
Angle "90"
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12930 / 6798 / 1820
Регистрация: 18.10.2014
Сообщений: 17,205
14.03.2017, 02:15
Лучший ответ Сообщение было отмечено imjonhson как решение

Решение

Цитата Сообщение от imjonhson Посмотреть сообщение
но значение явно не 0
Во-первых, с чего вы взяли, что сможете получить ровно 90 градусов? Ваш acos должен будет вернуть ровно число Пи-пополам, которое является иррациональным числом, точно в компьютере не представимым. Это не говоря уже о том что ваша запись числа Пи является не точной (и не может быть точной). Ясно, что эти погрешности исключают получение ровно 90 градусов.

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

C++
1
2
3
4
5
6
7
8
9
10
11
double length(const point& v)
{
  return sqrt(v.x * v.x + v.y * v.y);
}
 
double AngleTreePoints(const point& a, const point &b, const point &c)
{
  point ba = { a.x - b.x, a.y - b.y }, bc = { c.x - b.x, c.y - b.y };
  double sp = ba.x * bc.x + ba.y * bc.y;
  return acos(sp / (length(ba) * length(bc))) * 180 / 3.14159265;
}
В данном случае у вас под acos окажется точный ноль (на данных, приведенных в первом сообщении), но вышеописанные причины все равно не дадут вам получить ровно 90 в результате.
1
9 / 9 / 8
Регистрация: 02.01.2017
Сообщений: 262
14.03.2017, 06:13  [ТС]
Спасибо.
У меня не настолько высокоточные вычисления, единица-миллиметр, и округление даст возможную неточность +-1мм,что не есть харашо но не смертельно,другое дело что большинство алгоритмов завязаны на простых тригонометрических и др. функциях и эта мелочь может превратиться в более значительные погрешности.
как с этим борятся когда необходимо вычислить идеально точные данные, например при проектировании производства высокоточных приборов
0
14.03.2017, 08:34

Не по теме:

Что значит идеально точные? Не округляй до целых миллиметров.

0
9 / 9 / 8
Регистрация: 02.01.2017
Сообщений: 262
17.03.2017, 09:11  [ТС]
Цитата Сообщение от imjonhson Посмотреть сообщение
int LengthBetweenPoints(point a,point b) { return (int)sqrt(((double)b.y-(double)a.y)*((double)b.y-(double)a.y)+((double)b.x-(double)a.x)*((double)b.x-(double)a.x)); }
В этой функции тоже неточность теряется значение переделал:
C++
1
2
3
4
int LengthBetweenPoints(point a,point b)
{
     return (int)rint(sqrt((long double)((b.y-a.y)*(b.y-a.y)+(b.x-a.x)*(b.x-a.x))));
}
не помогло не подскажете что-то еще можно сделать?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12930 / 6798 / 1820
Регистрация: 18.10.2014
Сообщений: 17,205
17.03.2017, 09:16
Цитата Сообщение от imjonhson Посмотреть сообщение
не помогло не подскажете что-то еще можно сделать?
Ым...???

У вас функция до сих пор возвращает int, т.е. явным образом огрубляет результат до целого (!). Вам уже на это указывали. Какой смысл в ней что-то переделывать, если она у вас все равно возвращает int??? К чему здесь этот (long double)?
1
9 / 9 / 8
Регистрация: 02.01.2017
Сообщений: 262
17.03.2017, 10:00  [ТС]
ну... при проверке там где должно быть 600 выходит 599 +-1 и т.д.

Добавлено через 2 минуты
поэтому и добавил округление, в надежде что там небольшая погрешность, но если и округление не спасает тогда погрешность больше 0.5

Добавлено через 56 секунд
может есть более точные алгоритмы или более точная sqrt()?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12930 / 6798 / 1820
Регистрация: 18.10.2014
Сообщений: 17,205
17.03.2017, 10:48
Цитата Сообщение от imjonhson Посмотреть сообщение
но если и округление не спасает тогда погрешность больше 0.5
Это совсем не означает, что погрешность больше 0.5. Откуда вы такое взяли?

Приведение к типу int в языках С и С++ делается не путем округления к ближайшему целому, а путем отбрасывания дробной части, т.е. безусловного округления к нулю. Это значит, что если произошло отклонение вниз, то вы можете "повышать точность" хоть до позеленения, но все равно 599.999999999999998 превратится в 599, а не в 600. Никакой "погрешности больше 0.5" для этого не надо.

Если вы хотите округления к ближайшему целому - то делайте его явно (std::round и т.п.)
0
9 / 9 / 8
Регистрация: 02.01.2017
Сообщений: 262
17.03.2017, 12:03  [ТС]
http://www.cplusplus.com/reference/cmath/rint/

Добавлено через 1 минуту
может вы не заметили.....
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12930 / 6798 / 1820
Регистрация: 18.10.2014
Сообщений: 17,205
17.03.2017, 22:54
Цитата Сообщение от imjonhson Посмотреть сообщение
может вы не заметили.....
Да, каюсь, не заметил. Так а fesetround вы правильный сделали? (Хотя по умолчанию, оно должно быть "к ближайшему").
0
9 / 9 / 8
Регистрация: 02.01.2017
Сообщений: 262
18.03.2017, 03:43  [ТС]
на всякий случай попробовал, не помогло......
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
18.03.2017, 07:23
imjonhson, в твоём первом примере, если сделать возврат double, ответ 90 без округления.
1
9 / 9 / 8
Регистрация: 02.01.2017
Сообщений: 262
18.03.2017, 12:13  [ТС]
мне отдельно нужна функция длинны для других функций, а угол по трем точкам я уже сделал по примеру который дал TheCalligrapher
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
18.03.2017, 12:13
Помогаю со студенческими работами здесь

Составьте программу поиска меньшего из трех чисел с использованием подпрограммы-функции поиска из двух.
Помогите решить задачу, и составить для нее блок-схему. Условие такое: Составьте программу поиска меньшего из трех чисел с...

Рассчитать квадрат синуса угла, значение угла вводится с клавиатуры в градусах
Помогите. Нужно написать программу на СИ(в Visual Studio) которая расчитывает синус угла в квадрате , значение угла вводится с клавиатуры в...

Нарисовать движущуюся от левого нижнего угла экрана до правого верхнего угла окружность
Нарисовать, движущуюся от левого нижнего угла экрана до правого верхнего угла, окружность.Создавайте темы с осмысленными и понятными...

Составить функцию, которая по величине угла в радианах возвращает величину этого угла в градусах
Ребят я в этом деле новичок, позарез нужно сдать лабораторную( Составляю функцию а результат выводит 0. С процедурой программа работала....

Введите значение угла в градусах. Посчитать и вывести значения cos, sin и tg этого угла
Введите значение угла в градусах. Посчитайте и выведите значения cos, sin и tg этого угла. Результат решения задачи выведите на экран по...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru