I am in need of some help with angles.
Calculating bearings with the package fossil
and the function fossil::earth.bear
we obtain, according to the help,
"the bearing in degrees clockwise from True North between any two points on the globe".
I have a vector of angles obtained with this function, and I need to transform them so the origin (0º) is on the x axis (East) and the angles increment counterclockwise.
Basically I need a way to rotate 90º clockwise my angles (so the 0º will be on the x axis "facing East") and then calculate the angle in the opposite direction (counterclockwise).
Intuitively, I've tried adding 90º to my bearings (to rotate clockwise) and then substracting them from 360 (to calculate the angle in the "opposite direction").
However, it does not work and I highly suspect that there is a different thing to do for each quadrant, but I just can't figure it out.
Below a test with dummy data and polar histograms to prove that the solution is not working as the resulting vector bearings2
is not equivalent to the starting vector bearings
# Generate vector with 100 random values between 0 and 360
set.seed(123)
bearing <- runif(100, 0,360)
# generate a histogram with values binned every 5º
breaks = seq(0, 360, by=5)
bearing.cut = cut(bearing, breaks, right=FALSE)
bearing.freq = as.data.frame(table(bearing.cut))
bearing.freq$bearing.cut <- seq(5,360, by = 5)
#plot with ggplot
library(ggplot2)
ggplot(bearing.freq, aes(x = bearing.cut, y = Freq)) +
coord_polar(theta = "x", start = 0 direction = 1) + #start 0 for north, direction 1 for cloclwise
geom_bar(stat = "identity") +
scale_x_continuous(breaks = seq(0, 360, 5))
This is the plot that this creates Now I perform the mentioned operations in my bearing vector
bearing2 <- 360-(bearing-90)
# repeat the process to generate freq table and plot
breaks = seq(0, 360, by=5)
bearing.cut2 = cut(bearing2, breaks, right=FALSE)
bearing.freq2 = as.data.frame(table(bearing.cut2))
bearing.freq2$bearing.cut <- seq(5,360, by = 5)
#plot with ggplot
library(ggplot2)
ggplot(bearing.freq2, aes(x = bearing.cut2, y = Freq)) +
coord_polar(theta = "x", start = -pi/2, direction = -1) + # now start at E and counterclockwise
geom_bar(stat = "identity") +
scale_x_continuous(breaks = seq(0, 360, 5))
And this is the plot that this generates. Clearly, if my conversion was correct, these two plots should look the same... and they don't.
** I have edited as per Gregor's suggestion (and to set a seed so it is repeatable). Looks better but we lose all angles between 0º and 90º. Which reinforces my initial idea that there's a different operation to do for each quadrant, but still can't figure it out. Still, thanks for the tip!
Ok I think I figured it out but not really sure why it works. I'll just leave it here to mark the question as answered.
The solution is that, for the first quadrant (angles between 0º and 90º, we need to calculate the complementray angle so we need 90-bearing
. For the rest of the quadrants, we do what Gregor suggested(360-(bearing-90)
).
Below the complete code to a reproducible example
library(ggplot2)
set.seed(123)
# 0º at North and clockwise
bearing <- runif(100, 0,360)
#create histogram
breaks = seq(0, 360, by=5) # half-integer sequence
bearing.cut = cut(bearing, breaks, right=FALSE)
bearing.freq = as.data.frame(table(bearing.cut))
bearing.freq$bearing.cut <- seq(5,360, by = 5)
#plot
p1 <- ggplot(bearing.freq, aes(x = bearing.cut, y = Freq)) +
coord_polar(theta = "x", start =0, direction = 1) +
geom_bar(stat = "identity") +
scale_x_continuous(breaks = seq(0, 360, 5))
# transform to 0º at E and counterclockwise
bearing2 <- ifelse(bearing <=90, (90-bearing), (360 - (bearing - 90)))
#create histogram
bearing.cut2 = cut(bearing2, breaks, right=FALSE)
bearing.freq2 = as.data.frame(table(bearing.cut2))
bearing.freq2$bearing.cut <- seq(5,360, by = 5)
# plot
p2 <- ggplot(bearing.freq2, aes(x = bearing.cut, y = Freq)) +
coord_polar(theta = "x", start = -pi/2, direction = -1) +
geom_bar(stat = "identity") +
scale_x_continuous(breaks = seq(0, 360, 5))
require(gridExtra)
grid.arrange(p1, p2, ncol=2)