Преобразование декартовых углов в полярные/компасные/сторонние углы в R?

Это проблема, с которой я немного боролся и не смог найти там хорошего ответа. В конце концов я решил это в R, но подумал, что все равно опубликую его, если он понадобится другим. Если у кого-то есть более элегантное решение, я хотел бы его увидеть. Это немного грубая сила.

У меня есть ряд парных XY (декартовых) координат. Я могу легко получить углы между ними, используя простую команду atan(). Однако мне нужны углы в направлениях компаса (полярные? стороны света?) (где север = 0 °, восток = 90 ° и т. д.). Вот минимальный пример для получения данных и декартовых углов, и я разместил свое преобразование методом грубой силы в угол по компасу ниже. Преобразование градусов (из радианов) использует deg() из пакета 'circular'.

require(circular)
test <- data.frame(x=c(0,1,1,1,0,-1,-1,-1),y=c(1,1,0,-1,-1,-1,0,1))
test$angle <- deg(atan(test$y/test$x))
test

... производит

   x  y angle
1  0  1    90
2  1  1    45
3  1  0     0
4  1 -1   -45
5  0 -1   -90
6 -1 -1    45
7 -1  0     0
8 -1  1   -45

Обратите внимание, что углы в нижнем левом и верхнем левом квадрантах такие же, как и в нижнем и верхнем правом квадрантах, что приводит к потере направленности векторов.


person David Roberts    schedule 11.04.2014    source источник
comment
ты за atan2(x,y)?   -  person baptiste    schedule 11.04.2014
comment
Я попробовал atan2(), но он возвращает отрицательные углы в левых квадрантах, поэтому преобразование в полярные азимуты все еще требуется.   -  person David Roberts    schedule 11.04.2014


Ответы (3)


Во-первых, смещение углов для измерения оси Y (или Север = 0) можно легко выполнить, изменив угловую строку кода, вычитая 90 градусов (спасибо JK):

test$angle <- 90-deg(atan(test$y/test$x))

Однако преобразование левых векторов необходимо сохранить, поэтому моим решением была корректировка этих углов на основе знаков значений X и Y:

# Make new column for the polar/compass angles
test$polar <- test$angle
# Then make the necessary adjustments
# Adjustment for quadrant C (bottom left, 180 to 270°)
test[sign(test$x)==-1 & sign(test$y)==-1,"polar"] <- ((1-(test[sign(test$x)==-1 & sign(test$y)==-1,"angle"]/90))*90)+180
# Adjustment for quadrant D (top left, 270 to 360°)
test[sign(test$x)==-1 & sign(test$y)>=0, "polar"] <- abs(test[sign(test$x)==-1 & sign(test$y)>=0,"angle"])+180

... производство:

   x  y angle polar
1  0  1     0     0
2  1  1    45    45
3  1  0    90    90
4  1 -1   135   135
5  0 -1   180   180
6 -1 -1    45   225
7 -1  0    90   270
8 -1  1   135   315

Опять же, я публикую это как рабочее решение, но более элегантные или простые предложения также будут оценены!

person David Roberts    schedule 11.04.2014

Все линейно. Есть две трудности: направление увеличения угла - против часовой стрелки в декартовой системе и по часовой стрелке в навигационной системе, а декартов 0° соответствует 90° на карте. Мы можем решить первую проблему, изменив знак: N ‹= -C.

Теперь 0 отображается в 0. Мы хотим, чтобы 0 отображалось в 90, поэтому просто добавьте 90: N ‹= -C + 90.

Но, упс, это дает нам некоторые углы за пределами обычного диапазона 0-360. Но углы повторяются по модулю 360, поэтому мы легко это исправим: N ‹= -c + 90 по модулю 360.

Операторы по модулю расходятся во мнениях относительно того, как обращаться с отрицательными числами, поэтому на всякий случай сначала добавьте 360, чтобы устранить проблему: N ‹= (-C + 90 + 360) по модулю 360.

В Excel MOD(450 - C, 360) или в javascript, ((450 - C)) % 360. Боюсь, я не знаю R. [Но в Fortran IV это было бы FN = mod(450.0 - С, 360,0)]

person captain puget    schedule 29.04.2018

person    schedule
comment
Спасибо, Роланд. Кажется, это работает отлично. Мне придется немного разобрать его, так как я не знаком с некоторыми обозначениями комплексных чисел. - person David Roberts; 11.04.2014
comment
Что ж, построение z должно быть очевидным, а Arg просто дает угол полярной формы. - person Roland; 11.04.2014