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
9145
Цюрих
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
4656
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, Супермодераторы



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

Сейчас этот форум просматривают: нет зарегистрированных пользователей


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

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