5

I am building a manual / by-hand / judgmental factor rotation function.

Obviously, rotating the two-dimensional coordinate system 270° is the same as -90° and 720° is the same as .

I'd like to simplify user input such that all values are between -180° and 180°.

How can I do that elegantly in R?

Ps.: Or would it make more sense to store values from to 360°? Users may want to rotate clock- and counterclockwise, so I think -180 to 180 may be more intuitive from a UX point of view.

maxheld
  • 3,963
  • 2
  • 32
  • 51

3 Answers3

6

Something like?

x <- 90 + c(0,360,720)
x
# [1]  90 450 810

(x*pi/360) %% pi
# in radians:
#[1] 0.7853982 0.7853982 0.7853982

# in degrees
((x*pi/360) %% pi)*360/pi
#[1] 90 90 90
  • 1
    yes! Should've answered that myself, thanks so much. I wrapped your answer in a function and transformed it to `-180°` to `180°` in the below answer. – maxheld Jul 15 '15 at 11:12
5

Do you just want to have all numbers being their remainder mod 360?

So, you can do all sorts of sums and always end up with an answer between 0 and 360.

to_degrees <- function(x) x %% 360 
to_degrees(720)
[1] 0
to_degrees(-90)
[1] 270
to_degrees(300 + 100)
[1] 40

EDIT:

If you want the numbers to be between -180 and 180, just take away 180 at the end.

to_degrees <- function(x) x %% 360 -180

Now

  • 0 -> -180

  • 360 -> 180.

Mhairi McNeill
  • 1,951
  • 11
  • 20
  • yes, thanks – in addition, I wanted the values to be between `-180°` and `180°` (rather than `0°` and `360°`) for UX reasons. Or is that a stupid idea? Added clumsy solution below. – maxheld Jul 15 '15 at 11:11
1

based on @Pascal's answer, here's a slightly expanded version that (clumsily?) transforms the angles to a range from -180° to 180° (for UX reasons):

  simplify.angle <- function (angle.raw) {  # simplify angles to -180° to 180°
  angle.360 <- ((angle.raw*pi/360) %% pi)*360/pi
  if (angle.360 > 180) {
    angle.simple <- angle.360 - 360
  } else if (angle.360 < -180) {
    angle.simple <- angle.360 + 360
  } else {
    angle.simple <- angle.360
  }
  return(angle.simple)

}

This yields:

> sapply(c(-90, 270, 630, -450, -181), simplify.angle)
[1] -90 -90 -90 -90 179
maxheld
  • 3,963
  • 2
  • 32
  • 51