13
\$\begingroup\$

Given two points A and B, find the angle from line AO to line BO about point O where O is the origin ((0,0)). Additionally, the angle may be positive or negative depending on the positions of the points (see examples). Input will be points A and B, and may be given in any convenient form. Output will be the angle in degrees (but it is positive if AO is rotated counter-clockwise about the origin to get BO and negative if it is rotated clockwise). If the angle is 180 degrees you may return a negative or positive output. Similarly, the angle can be the positive or negative version of the same angle (90 deg is equal to -270 deg). Examples:

  • Input: A(5,5) B(5,-5) Output: -90 (AO is rotated -90 degrees to get BO).

  • Input: A(5,-5) B(5,5) Output: 90 (AO is rotated 90 degrees to get BO).

This is , so shortest code in bytes wins!

\$\endgroup\$
8
  • 1
    \$\begingroup\$ Your examples only have multiples of 90 degs in them. Is this true for our programs as well, or do they have to deal with arbitrary angles? \$\endgroup\$
    – Maltysen
    Commented Oct 26, 2015 at 4:25
  • 11
    \$\begingroup\$ How much precision is required? \$\endgroup\$ Commented Oct 26, 2015 at 4:35
  • 2
    \$\begingroup\$ Can we take input as two complex numbers? \$\endgroup\$
    – lirtosiast
    Commented Oct 26, 2015 at 4:51
  • 5
    \$\begingroup\$ What should the output be if one point is (0,0)? \$\endgroup\$
    – lirtosiast
    Commented Oct 26, 2015 at 5:28
  • 3
    \$\begingroup\$ Hint: The angle between AO and BO would usually be called angle AOB. \$\endgroup\$ Commented Oct 26, 2015 at 15:56

18 Answers 18

21
\$\begingroup\$

TI-BASIC, 13 bytes

For TI-83+/84+ series calculators.

Degree
Input Y
min(ΔList(R►Pθ(Ans,∟Y

To use this program, enter the list {x1,x2} through the Ans variable, and {y1,y2} at the prompt.

\$\endgroup\$
4
  • \$\begingroup\$ Is a TI-BASIC command a single byte? \$\endgroup\$
    – corsiKa
    Commented Oct 26, 2015 at 18:04
  • \$\begingroup\$ All commands here, except ΔList(, are one byte each. This includes R►Pθ(. \$\endgroup\$
    – lirtosiast
    Commented Oct 26, 2015 at 18:06
  • \$\begingroup\$ +1 just for using calculator programming. Takes me back to Trig and Calculus in my high school days. \$\endgroup\$ Commented Oct 26, 2015 at 18:26
  • \$\begingroup\$ Nice reference! Super cool. \$\endgroup\$
    – corsiKa
    Commented Oct 26, 2015 at 18:39
12
\$\begingroup\$

Pyth, 11 bytes

.t-FPM.jMQ6

Demonstration

Input is given in the format:

[[Bx, By], [Ax, Ay]]

If it is desired that A comes first, this can be changed for 1 byte.

Explanation:

.t-FPM.jMQ6
               Implicit: Q = eval(input())
      .jMQ     Convert input pairs to complex numbers.
    PM         Take their phases (angles in the complex plane).
  -F           Take the difference.
.t        6    Convert to degrees
\$\endgroup\$
10
\$\begingroup\$

CJam, 14 bytes

q~::ma:-P/180*

This is a full program that reads the input as [[Ax Ay] [Bx By]] from STDIN.

Try it online in the CJam interpreter.

How it works

q~             e# Read and evaluate all input.
  ::ma         e# Replace each point (x, y) with atan2(x, y).
               e# This returns its angle with the positive y axis, measured clockwise.
      :-       e# Compute the difference of the two resulting angles.
               e# This returns the angle between the points, measured counter-clockwise.
        P/180* e# Divide by Pi and multiply by 180 to convert to degrees.
\$\endgroup\$
2
  • 5
    \$\begingroup\$ Amusing that almost half of this program is just converting radians to degrees... \$\endgroup\$ Commented Oct 26, 2015 at 14:20
  • \$\begingroup\$ @DarrelHoffman I find it even more amusing that in Pyth the conversion is 3 bytes instead of 6, so if the challenge allowed for reporting in radians the languages would be tied \$\endgroup\$ Commented Oct 26, 2015 at 18:28
4
\$\begingroup\$

Minkolang 0.9, 112 bytes

I really want to implement trig functions as built-ins now...but this was fun! (Caveat: this outputs the positive angle difference, not the signed angle difference. Given my limitations, I think that's justified.)

4[n]0c2c*1c3c*+r4[2;1R]r+1R+0g*12$:;$:8[0ci2*3+d1R;0g$:1i1+[i2*1+d1+$:*]*]$+'3.141592654'25*9;$:$:12$:r-66*5**N.

Try it here.

Explanation

I'll post a fuller explanation if anyone wants it, but the gist of it is:

4[n]                                    Take in 4 integers from input
0c2c*1c3c*+                             dot product
r4[2;1R]r+1R+0g*12$:;                   magnitudes of vectors
$:                                      dot product divided by magnitudes (z)
8[0ci2*3+d1R;0g$:1i1+             *]    Taylor series for arccos
                     [i2*1+d1+$:*]      In particular, the coefficient (1/2 * 3/4 * ...)
$+                                      Add them all up!
'3.141592654'25*9;$:$:                  Divide by pi for converting to degrees
12$:r-                                  Subtract from 1/2 - I now have arccos(z)
66*5**                                  Convert to degrees
N.                                      Output as number and stop.
\$\endgroup\$
6
  • \$\begingroup\$ Does minkolang support comments? I couldn't find it on the readme. \$\endgroup\$ Commented Oct 26, 2015 at 15:11
  • 1
    \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ: It's just like other 2D languages - comments are whatever isn't reached by the program counter. \$\endgroup\$ Commented Oct 26, 2015 at 19:07
  • \$\begingroup\$ Oh, okay, then. That makes sense, dunno what I was thinking. \$\endgroup\$ Commented Oct 26, 2015 at 21:50
  • \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ: Your explicit use of comments in one of your answers makes me consider implementing similar functionality though. It's a neat idea and wouldn't be terribly hard for me to implement. \$\endgroup\$ Commented Oct 26, 2015 at 21:52
  • \$\begingroup\$ Thanks! :D Was it the Hello World challenge that you noticed the comments in (FYI the interpreter I have made for Simplex runs in different "modes": string mode and comment mode. It makes it really easy to parse and allows you to ignore signal characters of one mode whilst in the other.) \$\endgroup\$ Commented Oct 26, 2015 at 22:12
4
\$\begingroup\$

Mathematica, 22 bytes

{-1,1.}.ArcTan@@@#/°&

Example:

In[1]:= {-1,1.}.ArcTan@@@#/°&[{{5,5},{5,-5}}]

Out[1]= -90.

In[2]:= {-1,1.}.ArcTan@@@#/°&[{{5,-5},{5,5}}]

Out[2]= 90.
\$\endgroup\$
2
  • \$\begingroup\$ Will this work for inputs like {{0,1},{1,0}} \$\endgroup\$
    – lirtosiast
    Commented Oct 26, 2015 at 18:16
  • \$\begingroup\$ @ThomasKwa Of course it will. \$\endgroup\$
    – alephalpha
    Commented Oct 27, 2015 at 2:59
3
\$\begingroup\$

Julia, 18 25 bytes

f(A,B)=angle(B/A)/pi*180

This assumes that "any convenient form" already allows for A and B to be given as complex numbers. Then, the complex number arithmetic does all the heavy lifting.

Edit: converted snippet to function. 18 byte version only works in the Julia REPL.

\$\endgroup\$
0
3
\$\begingroup\$

Python 2.7, 73 Bytes

from math import*
f=lambda A,B:degrees(atan2(B[1],B[0])-atan2(A[1],A[0]))

Test:

f((5,5),(5,-5)) #-90.0
f((5,-5),(5,5)) #90.0
\$\endgroup\$
2
  • \$\begingroup\$ Welcome to PPCG! This is code-golf, so you should try to remove as many spaces as you can and shorten your code. \$\endgroup\$
    – mbomb007
    Commented Oct 26, 2015 at 18:45
  • 1
    \$\begingroup\$ You can make your code shorter by recklessly adding some *s all over the place \$\endgroup\$ Commented Oct 26, 2015 at 18:58
3
\$\begingroup\$

Octave, 43 bytes

f=@(a,b)(cart2pol(b)-cart2pol(a))(1)*180/pi

Input/Output:

octave:40> f([5,5],[5,-5])
ans = -90

octave:41> f([1,0],[0,1])
ans = 90
\$\endgroup\$
3
\$\begingroup\$

Javascript, 66 bytes

let f=(a,b)=>(Math.atan2(b.y,b.x)-Math.atan2(a.y,a.x))*180/Math.PI;

demo

\$\endgroup\$
1
  • \$\begingroup\$ 23 seconds before me =P Nice golf though! Btw, you can omit the let f=, and it's still considered valid as an anonymous function. \$\endgroup\$
    – Mwr247
    Commented Oct 26, 2015 at 20:43
2
\$\begingroup\$

Ruby, 64, 58 bytes

a=->(b){b.map{|c|Math.atan2(*c)}.reduce(:-)*180/Math::PI}

Usage

a.call [[5, 5], [5, -5]] # => -90.0
a.call [[5, -5], [5, 5]] # => 90.0
\$\endgroup\$
2
\$\begingroup\$

JavaScript, 49 bytes

(a,b)=>((c=Math.atan2)(...b)-c(...a))/Math.PI*180

Input is taken in form: [aY, aX], [bY, bX] (notice the reversed x/y)

\$\endgroup\$
0
2
\$\begingroup\$

CJam, 15 bytes

l~ma@@ma-P/180*

Thought I'll get in the CJam game as well. Try it online. Input is in form of bx by ax ay. Unfortunately, this is the shortest method of doing this challenge without copying Dennis' answer.

\$\endgroup\$
2
\$\begingroup\$

TeaScript, 28 bytes

I really should of implemented trig functions...

$.atan2(_[3]-y,z-x)*180/$.PI

Try it online input is a.x a.y b.x b.y

Explanation

$.atan2(       // Arc Tangent of...
    _[3] - y,  // 4th input - 2nd input
       z - x,  // 3rd input - 1st input
) * 180 / $.PI // Converts rad -> deg
\$\endgroup\$
1
\$\begingroup\$

Simplex v.0.7, 13 bytes

I'm glad I added mathrelations :D Unfortunately, I cannot take pointwise input. So, I input each point as a separate number (Ax, Ay, Bx, By). (I used this as a resource.)

(iRi~^fR)2LSo
(       )2    ~~ repeat inner twice
 iRi          ~~ take two chars of input (x,y)
    ~         ~~ switch top 2 on stack
     ^f       ~~ apply atan2 on (y,x)
       R      ~~ go right
          L   ~~ go left
           S  ~~ subtract result
            o ~~ output as number

I can save a char if I can take input as (Ay, Ax, By, Bx):

(iRi^fR)2LSo
\$\endgroup\$
1
\$\begingroup\$

C, 88 bytes

#include<math.h>
typedef double d;d g(d x,d y,d a,d b){return atan2(b-y,a-x)*180/M_PI;}

Requires compiling with GCC to take advantage of M_PI being defined in math.h as a part of GCC's built-in math constants. Try it online - since ideone doesn't use GCC (apparently), an additional few bytes are needed for enough digits of π to be accurate.

\$\endgroup\$
3
  • \$\begingroup\$ Or 45/atan(1) instead of 180/3.14159.... (in the online demo). \$\endgroup\$
    – CompuChip
    Commented Oct 27, 2015 at 13:16
  • \$\begingroup\$ @CompuChip I wasn't trying to make the online demo maximally golfed \$\endgroup\$
    – user45941
    Commented Oct 27, 2015 at 14:10
  • \$\begingroup\$ You can remove the brackets round atan2(b-y,a-x), although you then need a space after return so it only saves 1 byte. If you can use K&R style functions then double g(x,y,a,b)double x,y,a,b; also saves six bytes. \$\endgroup\$
    – Alchymist
    Commented Oct 30, 2015 at 9:58
1
\$\begingroup\$

Pascal, 68 Bytes

Pascal according to ISO standard 10206 “Extended Pascal” includes complex numbers as a built‑in data type.

function f(A,B:complex):real;begin f:=arg(B/A)*90/arg(cmplx(0,1))end

FreePascal, 71 Bytes

As of version 3.2.0 the FreePascal Compiler (FPC) does not (yet) support (all) Extended Pascal features, but the standard RTL (run‑time library) includes a custom ucomplex UCSD Pascal unit providing a record‑based complex number implementation.

uses uComplex;function f(A,B:complex):real;begin f:=180/pi*carg(B/A)end
\$\endgroup\$
0
\$\begingroup\$

Swift, 62 bytes

import Foundation
let f={(atan2($3,$2)-atan2($1,$0))*180/M_PI}

If you're on a Mac, you should be able to replace import Foundation with import Darwin to save 4 bytes.

\$\endgroup\$
0
\$\begingroup\$

R, 31 bytes

\(a,b,c,d)atan2(d-b,c-a)/pi*180

A built-in atan2 function.

Attempt This Online!

result:

> f(5,5,5,-5)
[1] -90
> f(5,-5,5,5)
[1] 90
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.