2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 Вычитание векторов в полярной системе координат.
Сообщение28.08.2017, 18:47 


28/08/17
5
Есть два вектора $A$ и $B$, заданные длиной и углом (от 0 до 360 градусов). Нужно найти угол вектора $C$, который получился в результате разницы векторов $A$ и $B$.

Перевел градусы в радианы, перевел вектор в декартову систему координат, а дальше не получается. Результаты этой функции не удовлетворительные. При некоторых входных значениях угол получается отрицательным, а величина больше чем при вычитании.
Код:
Vector Computing::lateralDem(Vector v1, Vector v2) {

   double a1 = v1.angle * PI / 180; // перевод из градусов в радианы
   double a2 = v2.angle * PI / 180; // перевод из градусов в радианы

   double x1 = v1.value * cos(a1); // перевод в декартову систему
   double y1 = v1.value * sin(a1); // перевод в декартову систему
   double x2 = v2.value * cos(a2); // перевод в декартову систему
   double y2 = v2.value * sin(a2); // перевод в декартову систему

   double x3 = x2 - x1;
   double y3 = y2 - y1;

   double value3 = sqrt(x3*x3 - y3*y3);
   double angle3 = atan2(y3, x3);

   return{ angle3 * 180 / PI, value3 };


}

 Профиль  
                  
 
 Posted automatically
Сообщение28.08.2017, 21:08 
Модератор


19/10/15
1196
 i  Тема перемещена из форума «Программирование» в форум «Карантин»
по следующим причинам:

- неправильно набраны формулы (краткие инструкции: «Краткий FAQ по тегу [math]» и видеоролик Как записывать формулы);
- отсутствуют собственные содержательные попытки решения задач(и).

Исправьте все Ваши ошибки и сообщите об этом в теме Сообщение в карантине исправлено.
Настоятельно рекомендуется ознакомиться с темами Что такое карантин и что нужно делать, чтобы там оказаться и Правила научного форума.

 Профиль  
                  
 
 Posted automatically
Сообщение28.08.2017, 21:53 
Модератор


19/10/15
1196
 i  Тема перемещена из форума «Карантин» в форум «Программирование»


-- 28.08.2017, 19:56 --

pavelpasha в сообщении #1243675 писал(а):
При некоторых входных значениях угол получается отрицательным
Логично, потому что atan2 возвращает угол от $-\pi$ до $+\pi$, нужно его просто сдвинуть куда надо.

pavelpasha в сообщении #1243675 писал(а):
double value3 = sqrt(x3*x3 - y3*y3);
Опечатка - должен быть плюс вместо минуса (а еще лучше вопользоваться функцией hypot)

 Профиль  
                  
 
 Re: Posted automatically
Сообщение28.08.2017, 22:16 


28/08/17
5
pavelpasha в сообщении #1243675 писал(а):
При некоторых входных значениях угол получается отрицательным
Логично, потому что atan2 возвращает угол от $-\pi$ до $+\pi$, нужно его просто сдвинуть куда надо.

pavelpasha в сообщении #1243675 писал(а):
double value3 = sqrt(x3*x3 - y3*y3);
Опечатка - должен быть плюс вместо минуса (а еще лучше вопользоваться функцией hypot)[/quote]

Я переделал(такой вариант уже был у меня кстати).
Код:
Vector Computing::lateralDem(const Vector& v1, const Vector& v2) {

   double a1 = v1.angle * PI / 180; // перевод из градусов в радианы
   double a2 = v2.angle * PI / 180; // перевод из градусов в радианы

   double x1 = v1.value * cos(a1); // перевод в декартову систему
   double y1 = v1.value * sin(a1); // перевод в декартову систему
   double x2 = v2.value * cos(a2); // перевод в декартову систему
   double y2 = v2.value * sin(a2); // перевод в декартову систему

   double x3 = x2 - x1;
   double y3 = y2 - y1;

   double value3 = sqrt(x3*x3 + y3*y3);
   double angle3 = atan(y3 / x3);
   if (x3 < 0)
   angle3 = angle3 + PI;
   //double angle3 = atan2(y3, x3);

   return{ angle3 * 180 / PI, value3 };


}


Для проверки я передаю туда
Код:
lateralDem({0, 100 }, {180, 100 });
т.е. два противоположно направленных вектора одинаковой длины и их разница должна ровняться нулю. Но функция возвращает: угол 180, значение 200.

 Профиль  
                  
 
 Re: Вычитание векторов в полярной системе координат.
Сообщение28.08.2017, 22:21 
Заслуженный участник
Аватара пользователя


16/07/14
8554
Цюрих
pavelpasha в сообщении #1243718 писал(а):
т.е. два противоположно направленных вектора одинаковой длины и их разница должна ровняться нулю
А теперь вспомните определение разности (и суммы) векторов.

 Профиль  
                  
 
 Re: Вычитание векторов в полярной системе координат.
Сообщение28.08.2017, 22:26 
Заслуженный участник


27/04/09
28128
Можно, кстати, поиграть в теорему косинусов для нахождения $c$, а потом найти угол как $$\arctg_2(b\sin\beta', b\cos\beta'-a) + \alpha,$$где $(a,\alpha),(b,\beta)$ — полярные координаты $A, B$, а $\beta'=\beta-\alpha$ должно быть известно ещё от применения теоремы косинусов. Всего получается 7 умножений, 5 сложений и 4 вызова функций (если не пользоваться предложенной функцией hypot, которая может быть примитивной, а также функцией, вычисляющей синус и косинус одного и того же аргумента за раз, если есть в библиотеке языка), тогда как в счёте в лоб получается 6 умножений, 3 сложения и 6 вызовов функций. Этот анализ не особо полон без сравнения точности вычислений — здесь может быть и хуже, не знаю. (UPD: а вообще время выполнения кода надо измерять (и грамотно), конечно. Но если сравнить с декартовым случаем, разница значительная.)

А ещё плохим решением видится хранение углов в градусах. Если вам нужно отображать их в градусах, это ещё не значит, что и хранить нужно тоже их — если арифметика с векторами делается намного чаще их отображения, лучше радианы. Да и полярные координаты вообще-то тоже сомнительны.

pavelpasha в сообщении #1243718 писал(а):
Я переделал(такой вариант уже был у меня кстати).
А вот это вы зря заменили atan2 на atan от частного. Теперь-то у вас углы будут точно иногда неправильными. Требовалось лишь прибавить $2\pi$, когда результат вышел отрицательным, и это у вас делается, но atan зачем?

 Профиль  
                  
 
 Re: Вычитание векторов в полярной системе координат.
Сообщение29.08.2017, 10:12 


28/08/17
5
mihaild в сообщении #1243719 писал(а):
А теперь вспомните определение разности (и суммы) векторов.

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

 Профиль  
                  
 
 Re: Вычитание векторов в полярной системе координат.
Сообщение29.08.2017, 12:16 
Заслуженный участник
Аватара пользователя


01/09/13
4325
pavelpasha в сообщении #1243775 писал(а):
исходя из этого необходимо получить вектор сноса.

?? Это вымпельный ветер? Или "вектор дрейфа"?

 Профиль  
                  
 
 Re: Вычитание векторов в полярной системе координат.
Сообщение29.08.2017, 13:38 
Заслуженный участник


01/06/15
1149
С.-Петербург
pavelpasha в сообщении #1243775 писал(а):
mihaild в сообщении #1243719 писал(а):
А теперь вспомните определение разности (и суммы) векторов.

Давайте я лучше опишу задачу в целом.
Описание задачи в целом не поможет, если Вы до сих пор в недоумении, почему $\vec{a}-(-\vec{a}) = 2\vec{a} $

pavelpasha в сообщении #1243775 писал(а):
Возможно я и метод решения неверный выбрал. Даны вектор скорости движения судна и вектор скорости ветра, исходя из этого необходимо получить вектор сноса.
Трудно сказать, пока нет чёткого определения, что подразумевается под "вектором сноса".

Кстати, для вычислений с векторами на плоскости, заданными в полярных координатах, может оказаться удобной арифметика комплексных чисел. Или вообще взять готовый пакет для векторных вычислений (если не стоит задача написать такой пакет самому).

 Профиль  
                  
 
 Re: Вычитание векторов в полярной системе координат.
Сообщение29.08.2017, 18:32 
Заслуженный участник


27/04/09
28128
Если дело просто в сложении векторов, и на способ их задания нет ограничений, решительно не понимаю, зачем выбирать полярные координаты.

 Профиль  
                  
 
 Re: Вычитание векторов в полярной системе координат.
Сообщение29.08.2017, 18:34 


28/08/17
5
arseniiv в сообщении #1243720 писал(а):
Можно, кстати, поиграть в теорему косинусов для нахождения $c$, а потом найти угол как $$\arctg_2(b\sin\beta', b\cos\beta'-a) + \alpha,$$где $(a,\alpha),(b,\beta)$ — полярные координаты $A, B$, а $\beta'=\beta-\alpha$ должно быть известно ещё от применения теоремы косинусов. Всего получается 7 умножений, 5 сложений и 4 вызова функций (если не пользоваться предложенной функцией hypot, которая может быть примитивной, а также функцией, вычисляющей синус и косинус одного и того же аргумента за раз, если есть в библиотеке языка), тогда как в счёте в лоб получается 6 умножений, 3 сложения и 6 вызовов функций. Этот анализ не особо полон без сравнения точности вычислений — здесь может быть и хуже, не знаю. (UPD: а вообще время выполнения кода надо измерять (и грамотно), конечно. Но если сравнить с декартовым случаем, разница значительная.)


Переделал первую формулу, должно работать.
Код:
   double a1 = v1.angle * PI / 180; //перевод из градусов в радианы
   double a2 = v2.angle * PI / 180; //перевод из градусов в радианы

   double x1 = v1.value * cos(a1); //перевод в декартову систему
   double y1 = v1.value * sin(a1); //перевод в декартову систему
   double x2 = v2.value * cos(a2); //перевод в декартову систему
   double y2 = v2.value * sin(a2); //перевод в декартову систему

   double x3 = x1 - x2;
   double y3 = y1 - y2;

   double angle3 = atan2(y3, x3);
   if (angle3 < 0) angle3 += PI;

   return{ angle3 / PI * 180, hypot(x3, y3)};


Но меня заинтересовал метод без перевода в декартову систему. И я с этого и начинал, но запнулся на нахождении угла и решил делать иначе. Вот на чем я остановился:
Код:
   double a1 = v1.angle * PI / 180; //перевод из градусов в радианы
   double a2 = v2.angle * PI / 180; //перевод из градусов в радианы

   double z = pow(v1.value, 2) + pow(v2.value, 2) - 2 * v1.value*v2.value*cos(a1  - a2); // --длина(по теореме косинусов)
   //double c = atan2(v1.value*cos(a1-a2),v1.value*sin(a1-a2)-v2.value)+a1; -- возвращает угол 45, в то время как для вычитания  {0;100} - {180;100} - верно будет 180
   double c = asin(sin(a1 - a2) * v2.value / z) +PI; // --угол(по теореме синусов)
   if (c < 0) c += PI;
   
   return{ c / PI * 180, sqrt(z) };


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

 Профиль  
                  
 
 Re: Вычитание векторов в полярной системе координат.
Сообщение29.08.2017, 19:58 
Заслуженный участник


27/04/09
28128
pavelpasha в сообщении #1243872 писал(а):
Но меня заинтересовал метод без перевода в декартову систему.
В нём есть смысл только если вы понимаете, зачем это делаете. Я упомянул его (и вывел формулу для угла) из чисто академического интереса.

pavelpasha в сообщении #1243872 писал(а):
А ваш вариант нахождения угла, почему-то тоже не возвращает нужный результат.
Код не проверял, но я мог ошибиться и в формуле. Выводится она так: поворачиваете систему координат, чтобы $\mathbf a$ лежал на полярной оси. Выводите угол, пользуясь декартовыми координатами, учитывая знание $c$ и то, что решением системы $x = r\cos\varphi,\; y = r\sin\varphi$ относительно $\varphi$ является $\varphi = \arctg_2(y, x)$, а потом поворачиваете систему координат назад, и, таким образом, добавляете к искомому углу $\alpha$. Перепроверьте — даже если моя формула верная (а я всё же считаю, что ошибок не было), появится понимание.

А по одному только синусу или косинусу угла вы его никогда, разумеется, не найдёте, если только он не обязан лежать в промежутке, на котором они инъективны. А у вас не обязан.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 12 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: Dmitriy40


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group