Last active
July 24, 2018 21:07
-
-
Save AdamSpannbauer/83d6d1446b9361a5e9928708aa9ebd4d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Create/Draw a Binary Fractal Tree | |
library(ggplot2) | |
library(uuid) | |
options(stringsAsFactors = FALSE) | |
# create line segment from (0, 0) to (0, len) to be trunk of fractal tree | |
create_trunk = function(len = 1) { | |
end_point = c(0, len) | |
trunk_df = data.frame(x=c(0, 0), | |
y=end_point, | |
id=uuid::UUIDgenerate()) | |
return(list(df=trunk_df, end_point=end_point)) | |
} | |
# creates end point of line segment to satisfy length and | |
# angle inputs from given start coord | |
gen_end_point = function(xy, len = 5, theta = 45) { | |
dy = sin(theta) * len | |
dx = cos(theta) * len | |
newx = xy[1] + dx | |
newy = xy[2] + dy | |
return(c(newx, newy)) | |
} | |
# create a single branch of fractal tree | |
# returns branch endpoint coords and a plotly line shape to represent branch | |
branch = function(xy, angle_in, delta_angle, len) { | |
end_point = gen_end_point(xy, len = len, theta = angle_in + delta_angle) | |
branch_df = as.data.frame(rbind(xy, end_point)) | |
rownames(branch_df) = NULL | |
names(branch_df) = c('x', 'y') | |
branch_df$id = uuid::UUIDgenerate() | |
return(list(df=branch_df, end_point=end_point)) | |
} | |
# helper function to aggregate branch objects into single branch object | |
collect_branches = function(branch1, branch2) { | |
return(list(df=rbind(branch1$df, branch2$df))) | |
} | |
# recursively create fractal tree branches | |
create_branches = function(xy, | |
angle_in = pi / 2, | |
delta_angle = pi / 8, | |
len = 1, | |
min_len = 0.01, | |
len_decay = 0.2) { | |
if (len < min_len) { | |
return(NULL) | |
} else { | |
branch_left = branch(xy, angle_in, delta_angle, len) | |
subranches_left = create_branches(branch_left$end_point, | |
angle_in = angle_in + delta_angle, | |
delta_angle = delta_angle, | |
len = len * len_decay, | |
min_len = min_len, | |
len_decay = len_decay) | |
branches_left = collect_branches(branch_left, subranches_left) | |
branch_right = branch(xy, angle_in, -delta_angle, len) | |
subranches_right = create_branches(branch_right$end_point, | |
angle_in = angle_in - delta_angle, | |
delta_angle = delta_angle, | |
len = len * len_decay, | |
min_len = min_len, | |
len_decay = len_decay) | |
branches_right = collect_branches(branch_right, subranches_right) | |
return(collect_branches(branches_left, branches_right)) | |
} | |
} | |
# create and draw binary fractal tree | |
draw_fractal_tree = function(trunk_len=10, | |
delta_angle = pi / 8, | |
len_decay=0.7, | |
min_len=0.25) { | |
trunk = create_trunk(trunk_len) | |
branches = create_branches(trunk$end_point, | |
delta_angle =delta_angle, | |
len = trunk_len * len_decay, | |
min_len = min_len, | |
len_decay = len_decay) | |
tree = collect_branches(trunk, branches)$df | |
ggplot(tree, aes(x, y, group=id)) + | |
geom_point(size=.5, aes(color=x)) + | |
geom_line() + | |
scale_color_gradientn(colours = rainbow(5)) + | |
guides(color=FALSE) + | |
theme_void() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment