knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width=8, fig.height=5 )
library(dplyr) library(ggplot2) library(dddr)
The R package dddr
works well with three-diensional spatial data. It gives three-dimensional objects like points, velocities, and rotations first-class vector status in R, enabling usage as column types within data.frame
and tibble
.
Vectors have addition and subtraction operations, as well as scalar multiplication.
spiral <- data.frame(i = seq(0, 10*pi, by=0.05)) %>% mutate( # vector3s are created using three numeric vector arguments, # and thanks to dplyr, can refer to other columns in the dataframe circular_part = vector3(x=cos(i), y=sin(i), z=0), forward_part = vector3(x=0, y=0, z=i/15), # vector3s can be added together and multiplied by numerics spiral_part = circular_part * i / 30 + forward_part ) ggplot(spiral, aes(x=spiral_part$x, y=spiral_part$y)) + geom_point() + geom_path() + coord_equal()
spiral %>% mutate(addition_example = spiral_part + vector3(1, 1, 0)) %>% ggplot() + geom_point(aes(x=spiral_part$x, y=spiral_part$y), color="black") + geom_path(aes(x=spiral_part$x, y=spiral_part$y), color="black") + geom_point(aes(x=addition_example$x, y=addition_example$y), color="blue") + geom_path(aes(x=addition_example$x, y=addition_example$y), color="blue") + coord_equal()
spiral %>% mutate(multiplication_example = spiral_part * 1.5) %>% ggplot() + geom_point(aes(x=spiral_part$x, y=spiral_part$y), color="black") + geom_path(aes(x=spiral_part$x, y=spiral_part$y), color="black") + geom_point(aes(x=multiplication_example$x, y=multiplication_example$y), color="blue") + geom_path(aes(x=multiplication_example$x, y=multiplication_example$y), color="blue") + coord_equal()
Vectors can be rotated using the rotate
function in many different ways. One approach is a very simple axis-angle.
spiral %>% mutate(axis_angle_rotation = rotate(spiral_part, axis=vector3(0, 1, 0), angle=pi/4)) %>% ggplot() + geom_point(aes(x=spiral_part$x, y=spiral_part$y), color="black") + geom_path(aes(x=spiral_part$x, y=spiral_part$y), color="black") + geom_point(aes(x=axis_angle_rotation$x, y=axis_angle_rotation$y), color="blue") + geom_path(aes(x=axis_angle_rotation$x, y=axis_angle_rotation$y), color="blue") + coord_equal()
Another approach uses from/to specific vectors.
spiral %>% mutate(from_to_rotation = rotate(spiral_part, from=vector3(0, 0, 1), to=vector3(-1, -1, -1))) %>% ggplot() + geom_point(aes(x=spiral_part$x, y=spiral_part$y), color="black") + geom_path(aes(x=spiral_part$x, y=spiral_part$y), color="black") + geom_point(aes(x=from_to_rotation$x, y=from_to_rotation$y), color="blue") + geom_path(aes(x=from_to_rotation$x, y=from_to_rotation$y), color="blue") + coord_equal()
There are a handful of other useful functions, including angle_between
, and vector projection and rejection.
spiral %>% mutate(angle = angle_between(spiral_part, vector3(0, 0, 0), origin=vector3(0, -2, 0))) %>% ggplot() + geom_point(aes(x=i, y=angle)) + geom_line(aes(x=i, y=angle))
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.