Title: | Generate ficus benjamina leaf shapes with bezier curves |
---|---|
Description: | This package can be used to generate shapes in the form of ficus benjamina (weeping fig) leaves with bezier curves. The main output of the package are dataframes containing all the information of these bezier curves. |
Authors: | Urs Wilke [aut, cre] |
Maintainer: | Urs Wilke <[email protected]> |
License: | MIT + file LICENSE |
Version: | 0.0.1 |
Built: | 2025-02-12 03:11:42 UTC |
Source: | https://github.com/urswilke/ggbenjamini |
Generate a branch of benjamini leaves
benjamini_branch( df_branch = tibble::tibble(x = c(70, 84, 126, 168), y = c(280, 245, 217, 217)), leaf_mean_dist_approx = 10, leaf_angle = 45, first_dir = sample(0:1, 1), leave_size_dist = spark_weibull(shape = 1.5, scale_factor = 0.8), leaf_angle_dist = spark_norm(mean = 0, sd = 3), last_angle_straight = TRUE, leaf_size_multiplicator = 1 )
benjamini_branch( df_branch = tibble::tibble(x = c(70, 84, 126, 168), y = c(280, 245, 217, 217)), leaf_mean_dist_approx = 10, leaf_angle = 45, first_dir = sample(0:1, 1), leave_size_dist = spark_weibull(shape = 1.5, scale_factor = 0.8), leaf_angle_dist = spark_norm(mean = 0, sd = 3), last_angle_straight = TRUE, leaf_size_multiplicator = 1 )
df_branch |
dataframe containing the 4 x & y bezier coordinates of a branch |
leaf_mean_dist_approx |
approximate distance of two leaves |
leaf_angle |
angle between the leaf stalks and the branch |
first_dir |
direction of the first leaf in the branch (0 for right; 1 for left) |
leave_size_dist |
Manipulate the sizes of the leaves with a spark function This function returns a function which itself returns a numerical vector of length of the number of leaves on the branch. The function will be rescaled (divided by it's maximum value). |
leaf_angle_dist |
Manipulate the leaf angles with a spark function This function returns a function which itself returns a numerical vector of length of the number of leaves on the branch. |
last_angle_straight |
Logical if the angle of the last leaf on the branch is very sharp (defaults to TRUE). |
leaf_size_multiplicator |
Multiply leaf size distribution with a factor. |
A dataframe containing the data for leaves on a branch (see example).
benjamini_branch() %>% tidyr::unite(b, i_part, i_leaf, element, remove = FALSE) %>% ggplot2::ggplot() + ggforce::geom_bezier(ggplot2::aes(x = x, y = y, group = b)) + ggplot2::coord_equal()
benjamini_branch() %>% tidyr::unite(b, i_part, i_leaf, element, remove = FALSE) %>% ggplot2::ggplot() + ggforce::geom_bezier(ggplot2::aes(x = x, y = y, group = b)) + ggplot2::coord_equal()
Generate bezier curve coordinates of a benjamini leaf
benjamini_leaf( leaf_params = gen_leaf_parameters(), omega = 0, xrot = leaf_params$x0, yrot = leaf_params$y0, precision = 2 )
benjamini_leaf( leaf_params = gen_leaf_parameters(), omega = 0, xrot = leaf_params$x0, yrot = leaf_params$y0, precision = 2 )
leaf_params |
parameter that control the leaf shape |
omega |
rotation angle of the leaf |
xrot |
x coordinate of pivot point (preset to leaf origin). |
yrot |
x coordinate of pivot point (preset to leaf origin). |
precision |
numeric precision of the output |
A dataframe conaining the data for the bezier curves of a leaf (see example).
df <- benjamini_leaf() df df %>% # This generated a unique identifier for the 4 rows of each bezier curve: tidyr::unite(b, element, i_part, remove = FALSE) %>% ggplot2::ggplot() + ggforce::geom_bezier(ggplot2::aes(x = x, y = y, group = b))
df <- benjamini_leaf() df df %>% # This generated a unique identifier for the 4 rows of each bezier curve: tidyr::unite(b, element, i_part, remove = FALSE) %>% ggplot2::ggplot() + ggforce::geom_bezier(ggplot2::aes(x = x, y = y, group = b))
Transform bezier dataframe to dataframe with path coordinates
bezier_to_polygon(df_benjamini_leaf, ..., n = 100)
bezier_to_polygon(df_benjamini_leaf, ..., n = 100)
df_benjamini_leaf |
Dataframe returned by |
... |
grouping variables in |
n |
number of points per bezier |
Dataframe with the coordinates of the bezier curve interpolations.
df_coords <- benjamini_leaf() %>% tidyr::unite(b, i_part, element, remove = FALSE) %>% bezier_to_polygon(b, i_part, element) df_coords df_coords %>% ggplot2::ggplot(ggplot2::aes(x = x, y = y, group = element, fill = element)) + ggplot2::geom_polygon()
df_coords <- benjamini_leaf() %>% tidyr::unite(b, i_part, element, remove = FALSE) %>% bezier_to_polygon(b, i_part, element) df_coords df_coords %>% ggplot2::ggplot(ggplot2::aes(x = x, y = y, group = element, fill = element)) + ggplot2::geom_polygon()
Generated with vignette("import_svg_bezier")
df_bezier_skeleton
df_bezier_skeleton
A data frame with 40 rows and 4 variables:
branch index
original point type in the svg file
x coordinate
y coordinate
Generate bezier end points
gen_benjamini_points(leaf_params = gen_leaf_parameters())
gen_benjamini_points(leaf_params = gen_leaf_parameters())
leaf_params |
parameters generated by |
tibble with absolute coordinates
gen_benjamini_points()
gen_benjamini_points()
Generate bezier slopes coordinates
gen_benjamini_slopes(leaf_params = gen_leaf_parameters())
gen_benjamini_slopes(leaf_params = gen_leaf_parameters())
leaf_params |
parameters generated by |
dataframe with sx1-4 in the x variable and sy1-4 in the y variable
gen_benjamini_slopes()
gen_benjamini_slopes()
Except the start point coordinates of the leaf origin x0
& y0
(arbitrarily set to 10 and 40) all coordinates are relative to this origin.
Most of the parameters are random generated, except for some of them (e.g.,
to close polygons, or to keep the stalk and the mid vein on the same
line).
gen_leaf_parameters( x0 = 10, y0 = 40, dx10 = sample(8:12, 1), dy10 = 0, dx21 = sample(12:20, 1), dy21 = sample(-4:-10, 1), dx32 = sample(10:18, 1), dy32 = stats::runif(1, 0.92 * (-dy21 - 1), 0.95 * (-dy21 - 1)), dx43 = sample(4:6, 1), dy43 = y0 + dy10 + dy21 + dy32, sx0 = stats::runif(1, 0, 0.1), sx1 = sample(1:3, 1), sx2 = sample(4:6, 1), sx3 = sample(2:4, 1), sx4 = stats::runif(1, 0, 0.2), sy0 = stats::runif(1, 0.5, 1), sy1 = sample(-4:-6, 1), sy2 = stats::runif(1, -0.5, 0.5), sy3 = stats::runif(1, 0.5, 1.5), sy4 = stats::runif(1, 0.2, 0.7), smx1 = sample(-5:-15, 1), smx2 = sample(-5:-15, 1), smy1 = stats::runif(1, -1, 1), smy2 = stats::runif(1, -1, 1) )
gen_leaf_parameters( x0 = 10, y0 = 40, dx10 = sample(8:12, 1), dy10 = 0, dx21 = sample(12:20, 1), dy21 = sample(-4:-10, 1), dx32 = sample(10:18, 1), dy32 = stats::runif(1, 0.92 * (-dy21 - 1), 0.95 * (-dy21 - 1)), dx43 = sample(4:6, 1), dy43 = y0 + dy10 + dy21 + dy32, sx0 = stats::runif(1, 0, 0.1), sx1 = sample(1:3, 1), sx2 = sample(4:6, 1), sx3 = sample(2:4, 1), sx4 = stats::runif(1, 0, 0.2), sy0 = stats::runif(1, 0.5, 1), sy1 = sample(-4:-6, 1), sy2 = stats::runif(1, -0.5, 0.5), sy3 = stats::runif(1, 0.5, 1.5), sy4 = stats::runif(1, 0.2, 0.7), smx1 = sample(-5:-15, 1), smx2 = sample(-5:-15, 1), smy1 = stats::runif(1, -1, 1), smy2 = stats::runif(1, -1, 1) )
x0 , y0
|
coordinates of the leaf origin |
dx10 , dy10 , dx21 , dy21 , dx32 , dy32 , dx43 , dy43
|
coordinates of the other bezier start & end points |
sx0 , sx1 , sx2 , sx3 , sx4
|
x coordinates of the control points |
sy0 , sy1 , sy2 , sy3 , sy4
|
y coordinates of the control points |
smx1 , smx2 , smy1 , smy2
|
x & y coordinates of the mid vein control points |
named list of all parameters
gen_leaf_parameters()
gen_leaf_parameters()
Generate bezier slopes of the line in the middle of the leaf
gen_middle_line_slopes(leaf_params = gen_leaf_parameters())
gen_middle_line_slopes(leaf_params = gen_leaf_parameters())
leaf_params |
parameters generated by |
A dataframe containing the coordinates of the two control points of the bezier curve defining the midvein of the leaf.
gen_middle_line_slopes()
gen_middle_line_slopes()
Generate a dataframe of one bezier curve
get_one_bezier(i, points_df, slopes_df)
get_one_bezier(i, points_df, slopes_df)
i |
number of the bezier |
points_df |
dataframe generated by |
slopes_df |
dataframe generated by |
A dataframe containing the information for one bezier curve in the format as needed by ggforce::geom_bezier
.
set.seed(123) leaf_params <- gen_leaf_parameters() points_df <- gen_benjamini_points() slopes_df <- gen_benjamini_slopes() df_bezier <- get_one_bezier(1, points_df, slopes_df) ggplot2::ggplot(df_bezier, ggplot2::aes(x = x, y = y)) + ggforce::geom_bezier()
set.seed(123) leaf_params <- gen_leaf_parameters() points_df <- gen_benjamini_points() slopes_df <- gen_benjamini_slopes() df_bezier <- get_one_bezier(1, points_df, slopes_df) ggplot2::ggplot(df_bezier, ggplot2::aes(x = x, y = y)) + ggforce::geom_bezier()
This function returns a function which itself returns a numerical vector of length of the number of leaves on the branch.
spark_norm(mean = 0, sd = 3)
spark_norm(mean = 0, sd = 3)
mean , sd
|
Parameters passed to |
dnorm() function with n_leaves as one of the arguments
spark_norm()
spark_norm()
This function returns a function which itself returns a numerical vector of
length n_leaves
, the number of leaves on the branch. These values serve
as relative multiplication factors of the sizes of the leaves of the branch.
(The maximum value of this distribution is then normalized to 1.)
spark_weibull(shape = 1.2, scale_factor = 0.5)
spark_weibull(shape = 1.2, scale_factor = 0.5)
shape , scale_factor
|
Parameters passed to |
dweibull() function depending on n_leaves as one of the arguments
#Mark the two consecutive pairs of parentheses: spark_weibull()(n_leaves = 10)
#Mark the two consecutive pairs of parentheses: spark_weibull()(n_leaves = 10)