mirror of
https://github.com/ryantimpe/brickr.git
synced 2026-01-06 05:39:34 -06:00
245 lines
11 KiB
Plaintext
245 lines
11 KiB
Plaintext
---
|
|
title: "The LEGO® System in R"
|
|
output:
|
|
github_document:
|
|
fig_width: 7.5
|
|
fig_height: 6
|
|
html_preview: false
|
|
---
|
|
|
|
```{r setup, include=FALSE}
|
|
knitr::opts_chunk$set(echo = TRUE)
|
|
|
|
library(brickr)
|
|
library(jpeg)
|
|
library(tidyverse)
|
|
```
|
|
|
|
# brickr <img src='man/figures/logo.png' align="right" height="138" />
|
|
<!-- <!-- badges: start -->
|
|
[](https://www.tidyverse.org/lifecycle/#maturing)
|
|
[](https://travis-ci.org/ryantimpe/brickr)
|
|
<!-- <!-- badges: end -->
|
|
|
|
## Overview
|
|
**brickr** is a package for bringing the LEGO® experience into the R and [tidyverse](https://www.tidyverse.org/) ecosystem.
|
|
|
|
The package is divided into 3 separate systems:
|
|
|
|
- [**Mosaics**](#mosaics): Convert image files into mosaics that could be built using LEGO® bricks.
|
|
- [**3D Models**](#3d-models): Build 3D LEGO® models from simple data formats & [rayshader](https://www.rayshader.com/).
|
|
- [**Charts**](#charts): A [ggplot2](https://ggplot2.tidyverse.org/) extension to generate plots that resemble LEGO® bricks.
|
|
|
|
brickr also includes tools help users create the Mosaics and 3D model output using real LEGO® elements.
|
|
|
|
Check out [brickr.org](http://brickr.org) for more detail!
|
|
|
|
### What's the point?
|
|
|
|
The goal of **brickr** is to provide a series of tools to integrate the LEGO® system with R by:
|
|
|
|
- Enhancing a real world building experience with mosaics, generated instructions, and piece counts.
|
|
- Generating interest in R and coding for new audiences with easy-to-create 3D models.
|
|
- or just embracing pure novelty.
|
|
|
|
*brickr is developed using publicly available information about LEGO® products and is not officially affiliated with The LEGO Group*
|
|
|
|
## Installation
|
|
``` r
|
|
# 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")
|
|
```
|
|
|
|
## Mosaics
|
|
|
|
The mosaic functions renders an imported JPG or PNG file using LEGO colors and bricks.
|
|
|
|
```{r m1_set, fig.width = 3, fig.height=3, echo = TRUE, message = FALSE, warning = FALSE}
|
|
demo_img = tempfile()
|
|
download.file("http://ryantimpe.com/files/mf_unicorn.PNG", demo_img, mode="wb")
|
|
|
|
mosaic1 <- png::readPNG(demo_img) %>%
|
|
image_to_mosaic(img_size = 36) #Length of each side of mosaic in "bricks"
|
|
|
|
#Plot 2D mosaic
|
|
mosaic1 %>% build_mosaic()
|
|
```
|
|
|
|
In general, any **brickr** function that begins with `build_` generates a graphical output from a **brickr** list object, generated from other functions.
|
|
|
|
### Customization
|
|
|
|
`image_to_mosaic()` can take a few important arguments. See `?image_to_mosaic()` for full detail.
|
|
|
|
- `img_size` Providing a single value, such as `48`, crops the image to a square. Inputting a 2-element array, `c(56, 48)`, will output a rectangular image of `c(width, height)`.
|
|
|
|
- `color_table` & `color_palette` Options to limit the color of bricks used in mosaics, as not all colors produced by LEGO are readily available. Set `color_palette` to 'universal' or `c('universal', 'generic')` to limit colors to the most common ones. Use a subset of the data frame `lego_colors` as the `color_table` to specify a custom palette.
|
|
|
|
- `method` Technique used to map image colors into the allowed brick colors. Defaults to 'cie94`, but other options include 'cie2000' and 'euclidean'. Also includes the option 'brickr_classic', used in previous version of the package.
|
|
|
|
## 3D Models
|
|
|
|
The `bricks_from_*` series of functions creates 3D models of LEGO bricks from a variety of input formats. These models are rendered using [Tyler Morgan-Wall](https://twitter.com/tylermorganwall)'s [rayshader](https://www.rayshader.com/) package.
|
|
|
|
- `bricks_from_table()` & `bricks_from_excel()` convert a matrix-shaped table of integers into LEGO bricks. For simple models, this table can be made manually using `data.frame()` or `tibble::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. `bricks_from_excel()` is a wrapper function to more easily build models designed using a Microsoft Excel template. Please see this repo: [brickr toybox](https://github.com/ryantimpe/brickr_toybox).
|
|
|
|
- `bricks_from_coords()` takes a data frame with `x`, `y`, & `z` integer values, and `Color` columns, where each combination of x, y, & z is a point in 3-dimensional space. Color must be an official LEGO color name from `build_colors()`. This format is much more flexible than `bricks_from_table()` and allows the programmatic development of 3D models.
|
|
|
|
- `bricks_from_mosaic()` converts a 2D [mosaic](#mosaics) object from an image into 3D LEGO models, respectively. `bricks_from_rayshader()` creates a LEGO model from the same input as `rayshader::plot_3d()`.
|
|
|
|
Pass the output from any `bricks_from_*()` function to `build_bricks()` to see the 3D model. The `brick_res` option allows for higher resolution bricks in 'hd' or 'uhd', which will take longer to render.
|
|
|
|
```{r bricks_1, echo=TRUE, warning=FALSE, message=FALSE, fig.width=3, fig.height=3}
|
|
library(brickr)
|
|
|
|
#This is a brick
|
|
brick <- data.frame(
|
|
Level="A",
|
|
X1 = rep(3,4), #The number 3 is the brickrID for 'bright red'
|
|
X2 = rep(3,4)
|
|
)
|
|
|
|
brick %>%
|
|
bricks_from_table() %>%
|
|
build_bricks(brick_res = "uhd")
|
|
|
|
rayshader::render_snapshot( clear = TRUE)
|
|
```
|
|
|
|
### Stacking bricks
|
|
|
|
The Level column in the input table determines the elevation of the bricks. `bricks_from_table()` will convert alphanumeric levels into a z coordinate.
|
|
|
|
For larger models, use `tibble::tribble()` to more easily visualize the model. For very large models, use a csv or Excel.
|
|
|
|
```{r bricks_5, echo=TRUE, warning=FALSE, message=FALSE, fig.width=4, fig.height=4}
|
|
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) %>%
|
|
build_bricks(theta = 210, brick_res = "uhd")
|
|
|
|
rayshader::render_snapshot(clear = TRUE)
|
|
```
|
|
|
|
### 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.
|
|
|
|
```{r bricks_6, echo=TRUE, warning=FALSE, message=FALSE, fig.width=5, fig.height=5}
|
|
radius <- 4
|
|
sphere_coords <- expand.grid(
|
|
x = 1:round((radius*2.5)),
|
|
y = 1:round((radius*2.5)),
|
|
z = 1:round((radius/(6/5)*2.5)) #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() %>%
|
|
build_bricks(brick_res = "uhd", phi = 30, theta = 30)
|
|
|
|
rayshader::render_snapshot(clear = TRUE)
|
|
```
|
|
|
|
### Examples
|
|
|
|
More examples using `bricks_from_table()` and `bricks_from_coords()` can be found at the links below.
|
|
|
|
- [**Get started**](https://gist.github.com/ryantimpe/a784beaa4f798f57010369329d46ce71) with the framework for building a brick from scratch.
|
|
- [**Build an owl**](https://gist.github.com/ryantimpe/ceab2ed6b8a4737077280fc9b0d1c886) with `bricks_from_table()` by manually placing each brick.
|
|
- Generate a punny [**random forest model**](https://gist.github.com/ryantimpe/a7363a5e99dceabada150a43925beec7) using `bricks_from_coords()` and {purrr}.
|
|
- [**brickr toybox**](https://github.com/ryantimpe/brickr_toybox) repo for tools and resources to get started.
|
|
|
|
## Charts
|
|
|
|
brickr includes functions to render [ggplot2](https://ggplot2.tidyverse.org/) bar charts as bricks with LEGO color themes. The main function is `geom_brick_col()`, which is the brickr equivalent of `geom_col()`. Additional functions are highly recommended to ensure that proper the chart is rendered in the proper functions and proportions.
|
|
|
|
```{r geom_brick, echo=TRUE, warning=FALSE, message=FALSE, fig.width=4, fig.height=4}
|
|
df <- data.frame(trt = c("a", "b", "c"), outcome = c(2.3, 1.9, 3.2))
|
|
|
|
#For official LEGO colors, use with scale_fill_brick and theme_brick.
|
|
ggplot(df, aes(trt, outcome)) +
|
|
geom_brick_col(aes(fill = trt)) +
|
|
scale_fill_brick() +
|
|
coord_brick() +
|
|
theme_brick()
|
|
|
|
```
|
|
|
|
Both `scale_fill_brick()` and `theme_brick()` take an input 'brick_theme', which ensures all colors match official LEGO brick colors. See `build_themes()` for a sample of all available brick theme.
|
|
|
|
```{r geom_brick2, echo=TRUE, warning=FALSE, message=FALSE, fig.width=4, fig.height=4}
|
|
df <- data.frame(trt = letters[1:6], outcome = rnorm(6, mean = 5, sd = 2))
|
|
|
|
use_theme <- "hp"
|
|
|
|
ggplot(df, aes(trt, outcome)) +
|
|
geom_brick_col(aes(fill = trt), two_knob = F) +
|
|
scale_fill_brick(use_theme) +
|
|
coord_brick_flip() +
|
|
theme_brick(use_theme) +
|
|
theme(legend.position = "none")
|
|
|
|
```
|
|
|
|
## IRL
|
|
|
|
Additional functions assist in the translation of brickr objects into actual LEGO bricks.
|
|
|
|
### Instructions
|
|
|
|
Use `build_instructions()` to break the mosaics and 3D models into easier-to-read steps for building the set. This defaults to 6 steps, but passing any integer value will generate that many steps.
|
|
|
|
```{r m1_instructions, fig.width = 8, fig.height=7, message = FALSE, warning = FALSE}
|
|
mosaic1 %>% build_instructions(9)
|
|
```
|
|
|
|
### Piece list and count
|
|
|
|
Use `build_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](https://shop.lego.com/en-US/Pick-a-Brick) section using the advanced search option. Alternatively, use `table_pieces()` to produce a data frame table of all required bricks.
|
|
|
|
```{r m1_pieces, fig.width = 8, fig.height=7, message = FALSE, warning = FALSE}
|
|
mosaic1 %>% build_pieces()
|
|
```
|