g o l f a t a n 2

18

A veces es realmente difícil convertir las coordenadas cartesianas en coordenadas (x,y)polares (r,phi). Si bien se puede calcular r = sqrt(x^2+y^2)con bastante facilidad, a menudo es necesario algún tipo de distinción de los casos cuando se calcula el ángulo phidebido arcsin, arccosy arctany todas las demás funciones trigonométricas tener un co-dominio que cada uno sólo vanos medio del círculo.

En muchos idiomas hay incorporados para convertir coordenadas rectangulares a polares, o al menos tienen una atan2función que, dada (x,y), calcula el ángulo phi.

Tarea

Su tarea es escribir un programa / función que tome dos coordenadas cartesianas (de coma flotante, no ambas cero) (x,y)y genere el ángulo polar correspondiente phi, donde phidebe estar en grados, radianes o grados (con grados me refiero a gradientes que son 1 / 400 del círculo completo), lo que sea más conveniente para usted.

El ángulo se mide en orientación positiva, y tenemos el ángulo cero para (1,0).

Detalles

Está prohibido utilizar muebles empotrados que permiten calcular el ángulo phidado dos coordenadas, incluyendo atan2, rect2polar, argOfComplexNumbery funciones similares. Sin embargo, puede usar las funciones trigonométricas habituales y sus reversos, que solo requieren un argumento. Cualquier símbolo de unidad es opcional.

El radio rdebe ser no negativo y phidebe estar en el rango [-360°, 360°](no importa si se emite 270°o no -90°).

Ejemplos

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°
falla
fuente
Precisión requerida en rads / grados?
Luis Mendo
Yo diría que una precisión aproximada de precisión de la máquina, dependiendo de qué aplicación se utiliza (float / double / lo que sea)
flawr
¿Podemos tomar la entrada como un solo número complejo?
Adám

Respuestas:

9

MATL , 12 bytes

yYy/X;0G0<?_

El resultado está en radianes.

Pruébalo en línea! O verificar todos los casos de prueba .

Explicación

MATL no tiene una atanfunción (sí atan2, pero no se puede usar para este desafío). Entonces recurrí a 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
Luis Mendo
fuente
¿Matl realmente no tiene valor absoluto incorporado? Si lo hace, probablemente podría usarlo para reemplazarlo 0<?_, reduciendo unos pocos bytes
Zwei
2
@Zwei tiene ( |). Pero aquí estoy cambiando signo del resultado basado en el signo de la segunda entrada , y. Además, ypuede ser 0, así que no puedo multiplicar pory/abs(y))
Luis Mendo
5

JavaScript (ES6), 50 40 bytes

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

El resultado está en radianes. Editar: guarde 10 bytes cuando noté que está permitido que el resultado esté entre -90 ° y 270 °. Versión anterior con -Math.PI<=result<Math.PI:

(x,y)=>(Math.atan(y/x)||0)+Math.PI*(x<0)*(y>0||-1)
Neil
fuente
Que unidades Por favor póngalos en su respuesta.
Solomon Ucko
¿Qué es la ||0de?
l4m2
@ l4m2 Para el x=y=0caso.
Neil
4

MATLAB / Octave, 24 bytes

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

Esto define una función anónima que produce el resultado en radianes.

Pruébalo con ideone .

Luis Mendo
fuente
3

Javascript ES6, 54 bytes

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

Utiliza radianes.

Mama Fun Roll
fuente
2

Gelatina , 11 bytes (no competitiva)

<0×ØP+÷@ÆṬ¥

La salida está en radianes. Desafortunadamente, Jelly tenía un error de signo en sus átomos de división, lo que hace que esta respuesta no compita debido a la corrección de errores requerida.

Pruébalo en línea! o verificar todos los casos de prueba (convertidos a grados).

Cómo funciona

<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.
Dennis
fuente
¿La corrección de errores cuenta como hacer que una respuesta no sea competitiva? Eso parece extraño. Si ya se especificó el comportamiento correcto, la corrección de errores no debería estar relacionada. (Después de todo, ¿quién sabe cuántas otras respuestas hizo sin competencia al arreglar un caso límite inadvertido?)
Mario Carneiro
@MarioCarneiro En PPCG, el intérprete define el idioma . Esto se debe principalmente a que es difícil juzgar las intenciones (y la mayoría de los esolangs realmente no tienen una especificación concisa), mientras que no se puede discutir con una implementación. Tenga en cuenta que alterar el intérprete no afecta la validez de las respuestas anteriores. Solo tienen que trabajar en alguna versión publicada del intérprete.
Dennis
Quiero decir que puede haber cambiado el comportamiento de las respuestas anteriores en alguna entrada que no se intentó en ese momento. ¿Cómo maneja PPCG los casos de prueba malos descubiertos después del hecho?
Mario Carneiro
Si los casos de prueba resultan insuficientes, se agregan más casos de prueba. Se esperan soluciones para todas las entradas válidas, no solo para los casos de prueba en la pregunta. Re: corrección de errores. Mi intérprete solo produjo el signo incorrecto de división por 0 ( -1÷0dado en influgar de -inf), por lo que es poco probable que afecte a la mayoría de los desafíos.
Dennis
2

Python 3, 75 67 bytes

8 bytes gracias a Dennis.

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

Ideone it!

Monja permeable
fuente
¿Tienes que escribir andy or?
flawr
¿Que más puedo hacer?
Leaky Nun
1
@flawr Python solo tiene andy or.
Dennis
2
pi*(x<0==y)or atan(y/(hypot(x,y)+x))*2Guarda algunos bytes.
Dennis
44
@flawr: &es un operador bit a bit.
vaultah
2

APL (Dyalog Unicode) , 12 10 bytes SBCS

-2 gracias a ngn.

Función de infijo tácito anónimo. Utiliza la fórmula de alephalpha . Toma xcomo argumento correcto y ycomo argumento izquierdo. El resultado está en radianes.

11○∘⍟0J1⊥,

Pruébalo en línea!

, concatenar el yyx

0J1⊥ Evaluar como base i dígitos (es decir, y i ¹ + x i ⁰)

 logaritmo natural de eso

 luego

11○ parte imaginaria de eso

Adán
fuente
1
consejo
ngn
@ngn Gracias.
Adám
11○∘⍟->12○
ngn
@ngn No puedes usar ...argOfComplexNumber
Adám
oh ... ya veo, lo siento
ngn
1

Mathematica, 16 bytes

No estoy seguro de si Logse considera como una función integrada que calcula el ángulo dado dos coordenadas.

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

Ejemplo:

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
fuente
¡Esa es una idea inteligente! ¿Podría agregar un ejemplo de cómo llamar a esta función?
flawr
1

lenguaje de máquina x86 (Linux de 32 bits), 25 13 bytes (sin competencia)

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

Para probarlo en línea , compile el siguiente programa C (no olvide -m32marcar en 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));
    }
  }
}
techo
fuente
1

J , 10 bytes

Función de infijo tácito anónimo. Utiliza la fórmula de alephalpha . Toma xcomo argumento izquierdo y ycomo argumento derecho. El resultado está en radianes.

11 o.^.@j.

Pruébalo en línea!

j. calcular x+ y× i

@ luego

^. logaritmo natural de eso

11 o. parte imaginaria de eso

Adán
fuente
0

Python 3, 65 bytes

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

Esto produce radianes en el rango [-π/2, 3π/2), equivalente a [-90, 270)grados.

Aleatorio832
fuente
0

Axioma, 58 bytes

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

prueba (solo uso acos () devuelve radiantes)

(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
fuente