Title: | Make Custom Arrowheads |
---|---|
Description: | The 'ggarrow' package is a 'ggplot2' extension that plots a variety of different arrow segments with many options to customize. The 'arrowheadr' package makes it easy to create custom arrowheads and fins within the parameters that 'ggarrow' functions expect. It has preset arrowheads and a collection of functions to create and transform data for customizing arrows. |
Authors: | W. Joel Schneider [aut, cre] |
Maintainer: | W. Joel Schneider <[email protected]> |
License: | CC0 |
Version: | 1.0.1 |
Built: | 2025-03-13 04:31:27 UTC |
Source: | https://github.com/wjschne/arrowheadr |
make arrowhead from list of bezier control points
arrow_head_bezier( x, rotate = 0, rescale = c(1, 1), nudge = c(0, 0), transformations = c("rotater", "rescaler", "nudger"), n = 101, plot = FALSE, show_controls = TRUE )
arrow_head_bezier( x, rotate = 0, rescale = c(1, 1), nudge = c(0, 0), transformations = c("rotater", "rescaler", "nudger"), n = 101, plot = FALSE, show_controls = TRUE )
x |
list of control points (as vectors or matrices) |
rotate |
rotation angle in radians |
rescale |
a single value or 2-length vector for scaling in x and y |
nudge |
a single value or 2-length vector for nudging in x and y |
transformations |
a vector of transformation functions |
n |
number of points in each bezier curve |
plot |
plot arrowhead if TRUE |
show_controls |
show control points if plot = TRUE |
a matrix
curved_arrowhead <- arrow_head_bezier(list( c(1, 0, .5, .5, .2, .5), c(.2, .5, .2, .1, -.1, .25, -.3, .25), c(-.3, .25, 0, 0, -.3, -.25), c(-.3, -.25, -.1, -.25, .2, -.1, .2, -.5), c(.2, -.5, .5, -.5, 1, 0) ), plot = TRUE)
curved_arrowhead <- arrow_head_bezier(list( c(1, 0, .5, .5, .2, .5), c(.2, .5, .2, .1, -.1, .25, -.3, .25), c(-.3, .25, 0, 0, -.3, -.25), c(-.3, -.25, -.1, -.25, .2, -.1, .2, -.5), c(.2, -.5, .5, -.5, 1, 0) ), plot = TRUE)
Make catenary arrowhead
arrow_head_catenary( a = 1, base_width = 0, thickness = 1.2, closed = FALSE, rotate = 0, rescale = c(1, 1), nudge = c(0, 0), transformations = c("rotater", "rescaler", "nudger"), n = 361, plot = FALSE )
arrow_head_catenary( a = 1, base_width = 0, thickness = 1.2, closed = FALSE, rotate = 0, rescale = c(1, 1), nudge = c(0, 0), transformations = c("rotater", "rescaler", "nudger"), n = 361, plot = FALSE )
a |
peakedness of the arch (near 0 is more flat, large like parabola) |
base_width |
width of the base of the arch |
thickness |
thickness of the top of the arch |
closed |
if TRUE, closed arch |
rotate |
rotation angle in radians |
rescale |
a single value or 2-length vector for scaling in x and y |
nudge |
a single value or 2-length vector for nudging in x and y |
transformations |
a vector of transformation functions |
n |
number of points in polygon |
plot |
plot arrowhead if TRUE |
a matrix
catenary <- arrow_head_catenary(plot = TRUE) stlouis <- arrow_head_catenary( plot = TRUE, a = 0.4, base_width = 0.2, thickness = .09 ) bluntnosed_catenary <- arrow_head_catenary( plot = TRUE, a = .2, thickness = 1.2 )
catenary <- arrow_head_catenary(plot = TRUE) stlouis <- arrow_head_catenary( plot = TRUE, a = 0.4, base_width = 0.2, thickness = .09 ) bluntnosed_catenary <- arrow_head_catenary( plot = TRUE, a = .2, thickness = 1.2 )
Make arrrowhead with ellipse
arrow_head_ellipse( a = 1, b = 1, superellipse = 2, rotate = 0, rescale = c(1, 1), nudge = c(0, 0), transformations = c("unitizer", "rotater", "rescaler", "nudger"), n = 361, plot = FALSE )
arrow_head_ellipse( a = 1, b = 1, superellipse = 2, rotate = 0, rescale = c(1, 1), nudge = c(0, 0), transformations = c("unitizer", "rotater", "rescaler", "nudger"), n = 361, plot = FALSE )
a |
width of ellipse |
b |
height of ellipse |
superellipse |
parameter for specifying superellipses. Can be of length 1 or 2 |
rotate |
rotation angle in radians |
rescale |
a single value or 2-length vector for scaling in x and y |
nudge |
a single value or 2-length vector for nudging in x and y |
transformations |
a vector of transformation functions |
n |
number of points in polygon |
plot |
plot arrowhead if TRUE |
a matrix
ellipsehead <- arrow_head_ellipse(plot = TRUE, b = .5) ellipsehead_spaced <- arrow_head_ellipse( plot = TRUE, b = .5, rescale = .45, nudge = c(.55, 0) ) # Make regular polygon with n - 1 sides pentagon <- arrow_head_ellipse(n = 6, plot = TRUE) # make a superellipses star4 <- arrow_head_ellipse(superellipse = .5, plot = TRUE) squircle <- arrow_head_ellipse(superellipse = 3, plot = TRUE, rotate = pi / 4) longboat <- arrow_head_ellipse(plot = TRUE, b = 1, a = 4, superellipse = c(3,.5))
ellipsehead <- arrow_head_ellipse(plot = TRUE, b = .5) ellipsehead_spaced <- arrow_head_ellipse( plot = TRUE, b = .5, rescale = .45, nudge = c(.55, 0) ) # Make regular polygon with n - 1 sides pentagon <- arrow_head_ellipse(n = 6, plot = TRUE) # make a superellipses star4 <- arrow_head_ellipse(superellipse = .5, plot = TRUE) squircle <- arrow_head_ellipse(superellipse = 3, plot = TRUE, rotate = pi / 4) longboat <- arrow_head_ellipse(plot = TRUE, b = 1, a = 4, superellipse = c(3,.5))
Make arrowheads with any function
arrow_head_function( .fun = stats::dnorm, lower_bound = -4, upper_bound = 4, ..., base_width = 0, thickness = 1.2, closed = TRUE, minimum_value = NA, rotate = 0, rescale = c(1, 1), nudge = c(0, 0), transformations = c("rotater", "rescaler", "nudger"), n = 1001, plot = FALSE )
arrow_head_function( .fun = stats::dnorm, lower_bound = -4, upper_bound = 4, ..., base_width = 0, thickness = 1.2, closed = TRUE, minimum_value = NA, rotate = 0, rescale = c(1, 1), nudge = c(0, 0), transformations = c("rotater", "rescaler", "nudger"), n = 1001, plot = FALSE )
.fun |
a function (defaults to dnorm) |
lower_bound |
lowest value passed to .fun |
upper_bound |
highest value passed to .fun |
... |
arguments passed to .fun |
base_width |
If closed, size of feet |
thickness |
If closed, thickness of shape (can be negative) |
closed |
make polygon closed |
minimum_value |
smallest value in function |
rotate |
rotation angle in radians |
rescale |
a single value or 2-length vector for scaling in x and y |
nudge |
a single value or 2-length vector for nudging in x and y |
transformations |
a vector of transformation functions |
n |
number of points in polygon |
plot |
plot arrowhead if TRUE |
a matrix
# A normal distribution xy <- arrow_head_function(dnorm, plot = TRUE) # if closed = FALSE, set thickness and base_width xy <- arrow_head_function(dnorm, plot = TRUE, closed = FALSE, thickness = 1.5, base_width = .25) # A cauchy distribution xy <- arrow_head_function(dt, df = 1, plot = TRUE) # open with thickness = 1.5 xy <- arrow_head_function( dt, df = 1, plot = TRUE, closed = FALSE, thickness = 1.5 ) # thickness > 2 creates a bulge xy <- arrow_head_function( dt, df = 1, lower_bound = -3.25, upper_bound = 3.25, closed = FALSE, thickness = 2.5, plot = TRUE, rescale = 1 / 3, nudge = c(2 / 3, 0) ) # Make a new function mytrident <- function(x, s = 160) { k <- length(x) y1 <- dbeta(x, shape1 = s, shape2 = s) * 2 y2 <- dbeta(x, shape1 = s * .9, shape2 = s * .1) y3 <- dbeta(x, shape1 = s * .1 , shape2 = s * .9) y1 + y2 + y3 } xy <- arrow_head_function( mytrident, lower_bound = 0, upper_bound = 1, plot = TRUE, minimum_value = -3, rescale = .5, nudge = c(.5, 0) )
# A normal distribution xy <- arrow_head_function(dnorm, plot = TRUE) # if closed = FALSE, set thickness and base_width xy <- arrow_head_function(dnorm, plot = TRUE, closed = FALSE, thickness = 1.5, base_width = .25) # A cauchy distribution xy <- arrow_head_function(dt, df = 1, plot = TRUE) # open with thickness = 1.5 xy <- arrow_head_function( dt, df = 1, plot = TRUE, closed = FALSE, thickness = 1.5 ) # thickness > 2 creates a bulge xy <- arrow_head_function( dt, df = 1, lower_bound = -3.25, upper_bound = 3.25, closed = FALSE, thickness = 2.5, plot = TRUE, rescale = 1 / 3, nudge = c(2 / 3, 0) ) # Make a new function mytrident <- function(x, s = 160) { k <- length(x) y1 <- dbeta(x, shape1 = s, shape2 = s) * 2 y2 <- dbeta(x, shape1 = s * .9, shape2 = s * .1) y3 <- dbeta(x, shape1 = s * .1 , shape2 = s * .9) y1 + y2 + y3 } xy <- arrow_head_function( mytrident, lower_bound = 0, upper_bound = 1, plot = TRUE, minimum_value = -3, rescale = .5, nudge = c(.5, 0) )
Make a harpoon arrowhead
arrow_head_harpoon( point_angle = 30, barb_angle = 20, degrees = TRUE, rotate = 0, rescale = c(1, 1), nudge = c(0, 0), transformations = c("unitizer", "rotater", "rescaler", "nudger"), plot = FALSE )
arrow_head_harpoon( point_angle = 30, barb_angle = 20, degrees = TRUE, rotate = 0, rescale = c(1, 1), nudge = c(0, 0), transformations = c("unitizer", "rotater", "rescaler", "nudger"), plot = FALSE )
point_angle |
angle of harpoon point |
barb_angle |
angle of harpoon barb |
degrees |
if TRUE, angles are in degrees instead of radians |
rotate |
rotation angle in radians |
rescale |
a single value or 2-length vector for scaling in x and y |
nudge |
a single value or 2-length vector for nudging in x and y |
transformations |
a vector of transformation functions |
plot |
plot arrowhead if TRUE |
a matrix
xy <- arrow_head_harpoon(plot = TRUE)
xy <- arrow_head_harpoon(plot = TRUE)
Make spirograph arrowheads
arrow_head_hypotrochoid( r = 4, R = 3, d = r, windings = r, rotate = 0, rescale = c(1, 1), nudge = c(0, 0), transformations = c("unitizer", "rotater", "rescaler", "nudger"), n = 361, plot = FALSE ) arrow_head_deltoid( d = 2.6, rotate = pi, rescale = c(1, 0.5), nudge = c(0, 0), transformations = c("unitizer", "rotater", "rescaler", "nudger"), n = 361, plot = FALSE )
arrow_head_hypotrochoid( r = 4, R = 3, d = r, windings = r, rotate = 0, rescale = c(1, 1), nudge = c(0, 0), transformations = c("unitizer", "rotater", "rescaler", "nudger"), n = 361, plot = FALSE ) arrow_head_deltoid( d = 2.6, rotate = pi, rescale = c(1, 0.5), nudge = c(0, 0), transformations = c("unitizer", "rotater", "rescaler", "nudger"), n = 361, plot = FALSE )
r |
cycling circle radius |
R |
fixed circle radius |
d |
pen distance |
windings |
windings |
rotate |
rotation angle in radians |
rescale |
a single value or 2-length vector for scaling in x and y |
nudge |
a single value or 2-length vector for nudging in x and y |
transformations |
a vector of transformation functions |
n |
number of points in polygon |
plot |
plot arrowhead if TRUE |
a matrix
star5 <- arrow_head_hypotrochoid(plot = TRUE, rotate = pi) star5_long <- arrow_head_hypotrochoid( plot = TRUE, r = 4, R = 3, rotate = pi, rescale = c(1, .4) ) deltoid_long <- arrow_head_deltoid(plot = TRUE, rescale = c(1,1)) deltoid_long <- arrow_head_deltoid(plot = TRUE) deltoid_spaced <- arrow_head_deltoid(plot = TRUE, rescale = c(.6,.3), nudge = c(.4, 0))
star5 <- arrow_head_hypotrochoid(plot = TRUE, rotate = pi) star5_long <- arrow_head_hypotrochoid( plot = TRUE, r = 4, R = 3, rotate = pi, rescale = c(1, .4) ) deltoid_long <- arrow_head_deltoid(plot = TRUE, rescale = c(1,1)) deltoid_long <- arrow_head_deltoid(plot = TRUE) deltoid_spaced <- arrow_head_deltoid(plot = TRUE, rescale = c(.6,.3), nudge = c(.4, 0))
Make arrowhead from preset icon
arrow_head_icon( x = "stardestoyer", rotate = 0, rescale = c(1, 1), nudge = c(0, 0), transformations = c("rotater", "rescaler", "nudger"), plot = FALSE )
arrow_head_icon( x = "stardestoyer", rotate = 0, rescale = c(1, 1), nudge = c(0, 0), transformations = c("rotater", "rescaler", "nudger"), plot = FALSE )
x |
name of icon: eiffel, viper, viper2, nighthawk, pantherxf70 |
rotate |
rotation angle in radians |
rescale |
a single value or 2-length vector for scaling in x and y |
nudge |
a single value or 2-length vector for nudging in x and y |
transformations |
a vector of transformation functions |
plot |
plot arrowhead if TRUE |
a matrix
starwars_stardestoyer <- arrow_head_icon(x = "stardestoyer", plot = TRUE) starwars_executor <- arrow_head_icon(x = "executor", plot = TRUE) eiffel <- arrow_head_icon(x = "eiffel", plot = TRUE) battlestar_galactica_viper <- arrow_head_icon(x = "viper", plot = TRUE) battlestar_galactica_viper2 <- arrow_head_icon(x = "viper2", plot = TRUE) nighthawk <- arrow_head_icon(x = "nighthawk", plot = TRUE) panther_xf70 <- arrow_head_icon(x = "pantherxf70", plot = TRUE)
starwars_stardestoyer <- arrow_head_icon(x = "stardestoyer", plot = TRUE) starwars_executor <- arrow_head_icon(x = "executor", plot = TRUE) eiffel <- arrow_head_icon(x = "eiffel", plot = TRUE) battlestar_galactica_viper <- arrow_head_icon(x = "viper", plot = TRUE) battlestar_galactica_viper2 <- arrow_head_icon(x = "viper2", plot = TRUE) nighthawk <- arrow_head_icon(x = "nighthawk", plot = TRUE) panther_xf70 <- arrow_head_icon(x = "pantherxf70", plot = TRUE)
Mimics tikz's latex arrowheads, but can make any arrowhead with 2 side curves and an underside.
arrow_head_latex( point = c(1, 0), sidecontrols = c(7/12, 1/12, -1/6, 1/4), p_barb = c(-2/3, 5/8), undercontrols = c(-1/4, 1/6), rotate = 0, rescale = c(1, 1), nudge = c(0, 0), transformations = c("rotater", "rescaler", "nudger"), n = 101, plot = FALSE )
arrow_head_latex( point = c(1, 0), sidecontrols = c(7/12, 1/12, -1/6, 1/4), p_barb = c(-2/3, 5/8), undercontrols = c(-1/4, 1/6), rotate = 0, rescale = c(1, 1), nudge = c(0, 0), transformations = c("rotater", "rescaler", "nudger"), n = 101, plot = FALSE )
point |
length-2 vector for point coordinates |
sidecontrols |
vector of coordinates for control points on sides |
p_barb |
length-2 vector for barb coordinates |
undercontrols |
vector of coordinates for control points on underside |
rotate |
rotation angle in radians |
rescale |
a single value or 2-length vector for scaling in x and y |
nudge |
a single value or 2-length vector for nudging in x and y |
transformations |
a vector of transformation functions |
n |
number of points in polygon |
plot |
plot arrowhead if TRUE |
a matrix
latex_prime <- arrow_head_latex(plot = TRUE) latex_prime_spaced <- arrow_head_latex(nudge = c(.45, 0), rescale = .55, plot = TRUE) latex_regular <- arrow_head_latex(undercontrols = NULL, plot = TRUE) latex_flat <- arrow_head_latex(sidecontrols = NULL, plot = TRUE) latex_pincer <- arrow_head_latex( sidecontrols = c(-.5,1, -.5, 2), undercontrols = c(.2,1.5), p_barb = c(-1,.5), nudge = c(.35,0), rescale = c(.65,.4), plot = TRUE)
latex_prime <- arrow_head_latex(plot = TRUE) latex_prime_spaced <- arrow_head_latex(nudge = c(.45, 0), rescale = .55, plot = TRUE) latex_regular <- arrow_head_latex(undercontrols = NULL, plot = TRUE) latex_flat <- arrow_head_latex(sidecontrols = NULL, plot = TRUE) latex_pincer <- arrow_head_latex( sidecontrols = c(-.5,1, -.5, 2), undercontrols = c(.2,1.5), p_barb = c(-1,.5), nudge = c(.35,0), rescale = c(.65,.4), plot = TRUE)
Make trefoil arrowhead
arrow_head_trefoil( rotate = 0, rescale = c(1, 1), nudge = c(0, 0), transformations = c("unitizer", "rotater", "rescaler", "nudger"), n = 361, plot = FALSE )
arrow_head_trefoil( rotate = 0, rescale = c(1, 1), nudge = c(0, 0), transformations = c("unitizer", "rotater", "rescaler", "nudger"), n = 361, plot = FALSE )
rotate |
rotation angle in radians |
rescale |
a single value or 2-length vector for scaling in x and y |
nudge |
a single value or 2-length vector for nudging in x and y |
transformations |
a vector of transformation functions |
n |
number of points in polygon |
plot |
plot arrowhead if TRUE |
a matrix
trefoil <- arrow_head_trefoil(plot = TRUE)
trefoil <- arrow_head_trefoil(plot = TRUE)
See https://en.wikipedia.org/wiki/Wittgenstein's_rod
arrow_head_wittgenstein_rod( fixed_point = c(1.1, 0), rod_length = 2.1, rotate = 0, rescale = c(1, 1), nudge = c(0, 0), transformations = c("unitizer", "rotater", "rescaler", "nudger"), n = 361, plot = FALSE )
arrow_head_wittgenstein_rod( fixed_point = c(1.1, 0), rod_length = 2.1, rotate = 0, rescale = c(1, 1), nudge = c(0, 0), transformations = c("unitizer", "rotater", "rescaler", "nudger"), n = 361, plot = FALSE )
fixed_point |
x and y coordinates of a point |
rod_length |
Length of rod |
rotate |
rotation angle in radians |
rescale |
a single value or 2-length vector for scaling in x and y |
nudge |
a single value or 2-length vector for nudging in x and y |
transformations |
a vector of transformation functions |
n |
number of points in polygon |
plot |
plot arrowhead if TRUE |
a matrix
candleflame <- arrow_head_wittgenstein_rod( fixed_point = c(-2.75, 0), rod_length = 3.75, nudge = c(1, 0), rescale = .95, plot = TRUE ) rocket <- arrow_head_wittgenstein_rod( fixed_point = c(1.1, 0), rod_length = 2.1, plot = TRUE, nudge = c(.1, 0), rescale = c(.90, .25) )
candleflame <- arrow_head_wittgenstein_rod( fixed_point = c(-2.75, 0), rod_length = 3.75, nudge = c(1, 0), rescale = .95, plot = TRUE ) rocket <- arrow_head_wittgenstein_rod( fixed_point = c(1.1, 0), rod_length = 2.1, plot = TRUE, nudge = c(.1, 0), rescale = c(.90, .25) )
Nudge columns of a matrix by fixed amounts
nudger(x, nudge)
nudger(x, nudge)
x |
a matrix |
nudge |
a single value or a vector with length equal to the number of columns in x |
matrix
nudger(matrix(0, nrow = 2, ncol = 2), nudge = c(0,1))
nudger(matrix(0, nrow = 2, ncol = 2), nudge = c(0,1))
Plot arrowhead
plot_arrowhead(x, displayline = TRUE, displaypoints = TRUE)
plot_arrowhead(x, displayline = TRUE, displaypoints = TRUE)
x |
2-column matrix |
displayline |
plot the display line |
displaypoints |
plot the 0,0 point and the 1,0 point |
plot
Good for making symmetrical arrowheads
reflecter(x, add_reflection = TRUE)
reflecter(x, add_reflection = TRUE)
x |
matrix |
add_reflection |
add to x in reverse order |
a matrix with y reversed sign and rows in reverse order
reflecter(diag(c(1,2)))
reflecter(diag(c(1,2)))
Rescale each column of a matrix
rescaler(x, magnitude)
rescaler(x, magnitude)
x |
a matrix |
magnitude |
a single value or a vector with length equal to the number of columns in x |
a matrix
rescaler(matrix(1, nrow = 2, ncol = 2), magnitude = c(2,3))
rescaler(matrix(1, nrow = 2, ncol = 2), magnitude = c(2,3))
reverses the order of rows or columns in a matrix
rev_matrix_rows(x) rev_matrix_cols(x)
rev_matrix_rows(x) rev_matrix_cols(x)
x |
matrix |
a matrix
rev_matrix_rows(diag(c(1,2)))
rev_matrix_rows(diag(c(1,2)))
Rotate a 2-column matrix
rotater(x, theta, center = c(0, 0), degrees = FALSE)
rotater(x, theta, center = c(0, 0), degrees = FALSE)
x |
a 2-column matrix |
theta |
angle |
center |
point of rotation |
degrees |
if TRUE, theta is in degrees instead of radians |
a rotated 2-column matrix
x <- matrix(seq(10), ncol = 2) rotater(x, pi)
x <- matrix(seq(10), ncol = 2) rotater(x, pi)
Do transformations in a desired order
transformer( x, rescale = c(1, 1), rotate = 0, nudge = 0, center = c(0, 0), degrees = FALSE, transformations = c("unitizer", "rescaler", "nudger", "rotater") )
transformer( x, rescale = c(1, 1), rotate = 0, nudge = 0, center = c(0, 0), degrees = FALSE, transformations = c("unitizer", "rescaler", "nudger", "rotater") )
x |
a 2-column matrix |
rescale |
a single value or a vector with length equal to the number of columns in x |
rotate |
angle in radians unless degrees is true |
nudge |
a single value or a vector with length equal to the number of columns in x |
center |
a single value or a vector with length equal to the number of columns in x |
degrees |
if TRUE, angles are degrees instead of radians |
transformations |
a vector of transformation functions |
a matrix
matrix(c(0,0,1,1), nrow = 2) |> transformer(transformations = "rotater", rotate = pi)
matrix(c(0,0,1,1), nrow = 2) |> transformer(transformations = "rotater", rotate = pi)
Fit matrix to unit circle
unitizer(x, center = rep(0, ncol(x)))
unitizer(x, center = rep(0, ncol(x)))
x |
matrix |
center |
center of matrix |
matrix
A = matrix(c(1, 2, -8,6, 9,5), ncol = 2, byrow = TRUE) unitizer(A) cA <- unitizer(A, center = colMeans(A)) plot(cA, xlim = c(-1, 1), ylim = c(-1, 1)) t <- seq(0,2*pi, length.out = 361) lines(cos(t), sin(t))
A = matrix(c(1, 2, -8,6, 9,5), ncol = 2, byrow = TRUE) unitizer(A) cA <- unitizer(A, center = colMeans(A)) plot(cA, xlim = c(-1, 1), ylim = c(-1, 1)) t <- seq(0,2*pi, length.out = 361) lines(cos(t), sin(t))
Convert a vector to a matrix
v2matrix(x, ncol = 2, byrow = TRUE)
v2matrix(x, ncol = 2, byrow = TRUE)
x |
vector |
ncol |
number of columns |
byrow |
logical. convert by row |
a matrix
v2matrix(c(1,2,3,4))
v2matrix(c(1,2,3,4))