г л л ф т н н 2

18

Иногда действительно трудно преобразовать декартовы координаты (x,y)в полярные (r,phi). Несмотря на то, что вы можете вычислить r = sqrt(x^2+y^2)довольно легко, вам часто нужно различать случаи при расчете угла, phiпотому что arcsin, arccosи, как arctanи все другие тригонометрические функции, имеют совместную область, каждая из которых охватывает только половину круга.

Во многих языках есть встроенные модули для преобразования прямоугольных координат в полярные или, по крайней мере, atan2функции, которая - учитывая (x,y)- вычисляет угол phi.

задача

Ваша задача - написать программу / функцию, которая принимает две (с плавающей точкой, а не обе нулевые) декартовы координаты (x,y)и выводит соответствующий полярный угол phi, где phiон должен быть в градусах, радианах или градусах (с оценками я имею в виду градианы, которые равны 1 / 400 полного круга), в зависимости от того, что вам удобнее.

Угол измеряется в положительной ориентации, и у нас есть нулевой угол для (1,0).

Детали

Вы не можете использовать встроенные модули , которые вычисляют угол phiдал две координаты, в том числе atan2, rect2polar, argOfComplexNumberи другие подобные функции. Однако вы можете использовать обычные тригонометрические функции и их обращения, которые принимают только один аргумент. Любые условные обозначения являются необязательными.

Радиус rдолжен быть неотрицательным и phiдолжен находиться в диапазоне [-360°, 360°](не важно, выводите вы 270°или -90°).

Примеры

Input       Output
(1,1)       45°
(0,3)       90°
(-1,1)      135°
(-5,0)      180°
(-2,-2)     225°
(0,-1.5)    270°
(4,-5)      308.66°
flawr
источник
Требуемая точность в градусах / градусах?
Луис Мендо
Я бы сказал с точностью до точности машины, в зависимости от того, какую реализацию вы используете (float / double /
what
Можем ли мы принять входные данные как одно комплексное число?
Адам

Ответы:

9

MATL , 12 байт

yYy/X;0G0<?_

Результат в радианах.

Попробуйте онлайн! Или проверьте все тестовые случаи .

объяснение

У MATL нет atanфункции (она есть atan2, но ее нельзя использовать для этой задачи). Поэтому я прибегнул к acos.

y     % Take x, y implicitly. Duplicate x onto the top of the stack
Yy    % Compute hypothenuse from x, y
/     % Divide x by hypothenuse
X;    % Arccosine (inverse of cosine function)
0G    % Push y again
0<    % Is it negative?
?_    % If so, change sign. Implicitly end conditional branch. Implicitly display
Луис Мендо
источник
Действительно ли в Matl нет встроенных абсолютных значений? Если это произойдет, вы могли бы использовать его для замены 0<?_, сбрив несколько байтов
Zwei
2
@ Zwei Это имеет ( |). Но здесь я меняю знак результата на основе знака второго входа , y. Кроме того, yможет быть 0, поэтому я не могу умножить наy/abs(y))
Луис Мендо
5

JavaScript (ES6), 50 40 байт

(x,y)=>(Math.atan(y/x)||0)+Math.PI*(x<0)

Результат в радианах. Редактировать: Сохранено 10 байт, когда я заметил, что результат может быть между -90 ° и 270 °. Предыдущая версия с -Math.PI<=result<Math.PI:

(x,y)=>(Math.atan(y/x)||0)+Math.PI*(x<0)*(y>0||-1)
Нил
источник
Какие единицы? Пожалуйста, вставьте их в свой ответ.
Соломон Уцко
Для чего ||0?
14 кв.
@ l4m2 Для x=y=0дела.
Нил
4

MATLAB / Octave, 24 байта

@(x,y)atan(y/x)+pi*(x<0)

Это определяет анонимную функцию, которая производит результат в радианах.

Попробуйте это на Ideone .

Луис Мендо
источник
3

Javascript ES6, 54 байта

(x,y,m=Math)=>x<0&!y?m.PI:m.atan(y/(m.hypot(x,y)+x))*2

Использует радианы.

Mama Fun Roll
источник
2

Желе , 11 байт (не конкурирует)

<0×ØP+÷@ÆṬ¥

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

Попробуйте онлайн! или проверьте все контрольные примеры (в градусах).

Как это устроено

<0×ØP+÷@ÆṬ¥  Main link. Left argument x. Right argument: y

<0           Compare x with 0.
  ×ØP        Multiply the resulting Boolean by Pi.
          ¥  Combine the two links to the left into a dyadic chain.
      ÷@     Divide y by x.
        ÆṬ   Apply arctan to the result.
     +       Add the results to both sides.
Деннис
источник
Считает ли исправление ошибок неконкурентным ответ? Это кажется странным. Если правильное поведение уже было определено, исправление не должно быть связано. (В конце концов, кто знает, сколько других ответов вы сделали неконкурентными, исправив незаметный крайний случай?)
Марио Карнейру
@MarioCarneiro На PPCG переводчик определяет язык . Это происходит главным образом потому, что трудно судить о намерениях (и у большинства esolangs на самом деле нет краткой спецификации), а с реализацией не поспоришь. Обратите внимание, что изменение интерпретатора не влияет на достоверность старых ответов. Они должны работать только в какой-то опубликованной версии переводчика.
Деннис
Я имею в виду, что вы, возможно, изменили поведение старых ответов на некоторых входах, которые не были предприняты в то время. Как PPCG обрабатывает плохие тестовые случаи, обнаруженные после факта?
Марио Карнейро
Если контрольных примеров окажется недостаточно, добавляются дополнительные тестовые примеры. Ожидаются решения для всех допустимых входных данных, а не только для тестовых случаев в вопросе. Re: исправление ошибки. Мой переводчик только выдал неправильный знак для деления на 0 ( -1÷0дал infвместо -inf), так что это вряд ли повлияет на большинство задач.
Деннис
2

Python 3, 75 67 байт

8 байтов благодаря Денису.

from math import*
lambda x,y:pi*(x<0==y)or atan(y/(hypot(x,y)+x))*2

Идео это!

Дрянная Монахиня
источник
Вы должны выписать andи or?
flawr 18.06.16
Что еще я могу сделать?
Утренняя монахиня
1
@ Flawr Python имеет только andи or.
Деннис
2
pi*(x<0==y)or atan(y/(hypot(x,y)+x))*2сохраняет несколько байтов.
Деннис
4
@flawr: &побитовый оператор.
vaultah
2

APL (Dyalog Unicode) , 12 10 байтов SBCS

-2 благодаря нгн.

Анонимная негласная инфиксная функция. Использует формулу алефальфа . Принимает в xкачестве правого аргумента и в yкачестве левого аргумента. Результат в радианах.

11○∘⍟0J1⊥,

Попробуйте онлайн!

, объединить yиx

0J1⊥ Оценить как базовые цифры i (т. Е. Y i ¹ + x i ⁰)

 натуральный логарифм этого

 тогда

11○ мнимая часть этого

Адам
источник
1
чаевые
нгн
@ngn Спасибо.
Адам
11○∘⍟->12○
ngn
@ngn Вы не можете использовать ...argOfComplexNumber
Adám
ох ... я вижу, извините
нгн
1

Mathematica, 16 байтов

Я не уверен, Logсчитается ли это встроенным, который рассчитывает угол с учетом двух координат.

N@Im@Log[#+I#2]&

Пример:

In[1]:= N@Im@Log[#+I#2]&[1,1]

Out[1]= 0.785398

In[2]:= N@Im@Log[#+I#2]&[4,-5]

Out[2]= -0.896055
alephalpha
источник
Это умная идея! Не могли бы вы добавить пример, как вызвать эту функцию?
Flawr
1

машинный язык x86 (32-битный Linux), 25 13 байтов (неконкурентный)

0:       55                      push   %ebp
1:       89 e5                   mov    %esp,%ebp
3:       dd 45 08                fldl   0x8(%ebp)
6:       dd 45 10                fldl   0x10(%ebp)
9:       d9 f3                   fpatan  
b:       c9                      leave
c:       c3                      ret

Для того, чтобы попробовать его в Интернете , скомпилируйте следующую программу на C (не забудьте -m32флаг x86_64)

#include<stdio.h>
#include<math.h>
const char j[]="U\x89\xe5\335E\b\335E\20\xd9\xf3\xc9\xc3";
int main(){
  for(double f=-1;f<1;f+=.1){
    for(double g=-1;g<1;g+=.1){
      printf("%.2f %.2f %f %f\n",f,g,atan2(f,g),((double(*)(double,double))j)(f,g));
    }
  }
}
ceilingcat
источник
1

J , 10 байт

Анонимная негласная инфиксная функция. Использует формулу алефальфа . Принимает xкак левый аргумент и yкак правый аргумент. Результат в радианах.

11 o.^.@j.

Попробуйте онлайн!

j. рассчитать x+ y× я

@ тогда

^. натуральный логарифм этого

11 o. мнимая часть этого

Адам
источник
0

Python 3, 65 байт

from math import*
f=lambda x,y:atan(y/x if x else y*inf)+pi*(x<0)

Это выводит радианы в диапазоне [-π/2, 3π/2), эквивалентном [-90, 270)градусам.

Random832
источник
0

Аксиома, 58 байт

f(a,b)==(a=0 and b=0=>%i;sign(b)*acos(a*1./sqrt(a^2+b^2)))

test (я использую только acos (), он возвращает радианты)

(40) -> [[a,b,f(a,b)*180/%pi] for a in [1,0,-1,-5,-2,0,4] for b in [1,3,1,0,-2,-1.5,-5] ]
   (40)
   [[1.0,1.0,45.0], [0.0,3.0,90.0], [- 1.0,1.0,135.0], [- 5.0,0.0,180.0],
    [- 2.0,- 2.0,- 135.0], [0.0,- 1.5,- 90.0],
    [4.0,- 5.0,- 51.3401917459 09909396]]
                                            Type: List List Complex Float
RosLuP
источник