Lego Mosaics Using R
source link: https://www.tuicool.com/articles/hit/yyUzQjq
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
LEGO Mosaics in R
brickr
Overview
brickris a package for creating LEGO-esque 2D and 3D models using the R tidyverse and Tyler Morgan-Wall ’s rayshader package.
The package has two key uses:
- Converting image files in to 2D and 3D LEGO mosaics
- Building 3D LEGO models from simple data frames
Installation
# To install the latest version from Github: # install.packages("devtools") devtools::install_github("ryantimpe/brickr") #For 3D features, rayshader is also required. install.packages("rayshader")
3D Models
Currently, 3D models can be built from one of two data input formats: bricks_from_table()
or bricks_from_coords()
.
These functions are very experimental and will change. Better documentation will be released soon.
-
bricks_from_table()
converts a matrix-shaped table of integers into LEGO bricks. For simple models, this table can be made manually usingdata.frame()
ortibble::tribble()
. For more advanced models, it’s recommended you use MS Excel or a .csv file. The left-most column in the table is associated with the Level or z-axis of the model. The function by default converts this to numeric for you. Each other column is an x-coordinate and each row is a y-coordinate. More flexible inputs will be available in a future release. -
bricks_from_coords()
takes a data frame withx
,y
, &z
integer values, andColor
columns, where each combination of x, y, & z is a point in 3-dimensional space. Color must be an official LEGO color name fromdisplay_colors()
. This format is much more flexible thanbricks_from_table()
and allows the programatic development of 3D models.
Pass the output from any bricks_from_*()
function to display_bricks()
to see the 3D model.
library(brickr) #This is a brick brick <- data.frame( Level="A", X1 = rep(1,4), X2 = rep(1,4) ) brick
## Level X1 X2 ## 1 A 1 1 ## 2 A 1 1 ## 3 A 1 1 ## 4 A 1 1
brick %>% bricks_from_table() %>% display_bricks() rayshader::render_snapshot()
Brick Colors
There are 2 ways to assign the color of the bricks. The display_colors()
function helps with ID numbers and names
-
Use the
brickrID
value instead of ‘1’ in the model input table. Values of ‘0’ are blank spaces. -
Create a table of color assignments and pass this to
bricks_from_table()
brick_colors <- data.frame( .value = 1, Color = "Bright blue" ) brick %>% bricks_from_table(brick_colors) %>% display_bricks() rayshader::render_snapshot()
Stacking bricks
The Level column in the input table determines the height of the bricks. bricks_from_table()
will convert alphanumeric levels into a z coordinate.
# A is the bottom Level, B is the top brick <- data.frame( Level= c(rep("A",4), rep("B",4)), X1 = rep(1,4), X2 = rep(1,4) ) brick %>% bricks_from_table(brick_colors) %>% display_bricks() rayshader::render_snapshot()
The same process works with many levels
#You can stack many bricks ---- brick <- data.frame( Level="A", X1 = rep(1,4), X2 = rep(1,4) ) #... And they can all be different colors ---- 1:10 %>% purrr::map_df(~dplyr::mutate(brick, Level = LETTERS[.x], X1 = .x, X2 = .x)) %>% bricks_from_table() %>% display_bricks() rayshader::render_snapshot()
Full Models
For larger models, use tibble::tribble()
to more easily visualize the model. For very large models, use MS Excel.
my_first_model <- tibble::tribble( ~Level, ~X1, ~X2, ~X3, ~x4, ~x5, ~X6, ~x7, ~x8, "A", 1, 1, 1, 0, 1, 1, 1, 1, "A", 1, 0, 0, 0, 0, 0, 0, 1, "A", 1, 0, 0, 0, 0, 0, 0, 1, "A", 1, 1, 1, 1, 1, 1, 1, 1, "B", 1, 0, 1, 0, 1, 1, 0, 1, "B", 1, 0, 0, 0, 0, 0, 0, 1, "B", 1, 0, 0, 0, 0, 0, 0, 1, "B", 1, 0, 1, 0, 0, 1, 0, 1, "C", 1, 1, 1, 1, 1, 1, 1, 1, "C", 1, 0, 0, 0, 0, 0, 0, 1, "C", 1, 0, 0, 0, 0, 0, 0, 1, "C", 1, 1, 1, 1, 1, 1, 1, 1, "D", 2, 2, 2, 2, 2, 2, 2, 2, "D", 1, 0, 0, 0, 0, 0, 0, 1, "D", 1, 0, 0, 0, 0, 0, 0, 1, "D", 2, 2, 2, 2, 2, 2, 2, 2, "E", 0, 0, 0, 0, 0, 0, 0, 0, "E", 2, 2, 2, 2, 2, 2, 2, 2, "E", 2, 2, 2, 2, 2, 2, 2, 2, "E", 0, 0, 0, 0, 0, 0, 0, 0 ) brick_colors <- tibble::tribble( ~`.value`, ~Color, 1, "Bright blue", 2, "Dark orange" ) my_first_model %>% bricks_from_table(brick_colors) %>% display_bricks(theta = 210) rayshader::render_snapshot()
Programmatically build models
Use bricks_from_coords()
to programmatically build 3D LEGO models instead of manually drawing them in a spreadsheet or table. Here you must provide whole number coordinates for x, y, and z, along with an official LEGO color name for each point.
radius <- 4 sphere_coords <- expand.grid( x = 1:round((radius*2.5)), y = 1:round((radius*2.5)), z = 1:round((radius/(6/5)*3)) #A brick is 6/5 taller than it is wide/deep ) %>% mutate( #Distance of each coordinate from center dist = (((x-mean(x))^2 + (y-mean(y))^2 + (z-mean(z))^2)^(1/2)), Color = case_when( #Yellow stripes on the surface with a 2to4 thickness between(dist, (radius-1), radius) & (x+y+z) %% 6 %in% 0:1 ~ "Bright yellow", #Otherwise, sphere is blue dist <= radius ~ "Bright blue" )) sphere_coords %>% bricks_from_coords() %>% display_bricks(phi = 30, theta = 30) rayshader::render_snapshot()
Mosaics
The mosaic functions renders an imported JPG or PNG file using LEGO colors and bricks. The resulting mosaic can be viewed in 2D and 3D. A full explanation can be found on this blog post , this follow-up post ,and this third post .
mosaic1 <- jpeg::readJPEG("Images/goldengirls.jpg") %>% image_to_bricks(img_size = 48) #Length of each side of mosaic in "bricks" #Plot 2D mosaic mosaic1 %>% display_set()
If you had previously created mosaics before the package release, the script below will still work.
mosaic1 <- jpeg::readJPEG("Images/goldengirls.jpg") %>% scale_image(img_size = 48) %>% #Length of each side of mosaic in "bricks" legoize() %>% collect_bricks()
2D Mosaics
image_to_bricks()
can take a few important arguments:
-
img_size
Providing a single value, such as48
, crops the image to a square. Inputting a 2-element array,c(56, 48)
, will output a rectangular image ofc(width, height)
. -
color_table
Data frame of possible brick colors in the mosaic. Defaults to the included data setlego_colors
. -
brightness
adjusts the light of the image. Values greater than 1 will lighten the image, while value less than 1 will darken it.
display_set()
creates a ggplot of the image.
3D Mosaics
Two additional functions can convert the image_to_bricks()
output into a 3D mosaic using the rayshader package by Tyler Morgan-Wall .
-
collect_3d()
translates the 2D LEGO mosaic into two matrices - one for the color image and one for the elevation of each point on the image. By default, the produced image has the height of 6 LEGO plates (2 LEGO bricks) with lighter colors having a higher elevation. Usemosaic_height
to change the height of the mosaic and sethighest_el = 'dark'
to set the darker colors as the tallest bricks. -
display_3d()
simply callsrayshader::plot_3d()
, but pulls both the hillshade and elevation matrices from the output ofcollect_3d()
and fixes some of the arguments. See?rayshader::plot_3d()
for more information.
library(rayshader) mosaic1 %>% collect_3d() %>% display_3d(fov=0,theta=-20,phi=30,windowsize=c(1000,800),zoom=0.7) render_snapshot()
LEGO Mosaics IRL
Additional functions assist in the translation from the LEGO mosaic image into a real LEGO set.
Instructions
Use generate_instructions()
to break the LEGO mosaic image into easier-to-read steps for building the set. This defaults to 6 steps, but passing any integer value will generate that many steps.
mosaic1 %>% generate_instructions(9)
Piece list and count
Use display_pieces()
to generate a graphic and count of all required plates or bricks (for stacked mosaics). These are sorted by color and size for easy purchase on LEGO.com’s Pick-a-Brick section using the advanced search option. Alternatively, use table_pieces()
to produce a data frame table of all required bricks.
mosaic1 %>% display_pieces()
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK